Benutzer mit den meisten Antworten
Per Reflection.Emit erstellte Klasse INotifyPropertyChanged Interface korrekt einbinden

Frage
-
Ich möchte in eine mit Reflection.Emit erstellte Klasse das INotifyPropertyChanged Interface einbinden.
Ich binn mir nicht siche wo der fehler liegt, villeicht schafft es jemand das Problem zu lösen.
TypeBuilder tb; //=... //... FieldBuilder eventField = tb.DefineField("m_PropertyChanged", typeof(PropertyChangedEventHandler), FieldAttributes.Public); EventBuilder eb = tb.DefineEvent("PropertyChanged", EventAttributes.None, typeof(PropertyChangedEventHandler)); MethodBuilder mbEV = tb.DefineMethod("remove_PropertyChanged", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual , null, new[] { typeof(PropertyChangedEventHandler) }); MethodImplAttributes eventMethodFlags = MethodImplAttributes.Managed; mbEV.SetImplementationFlags(eventMethodFlags); var removeIl = mbEV.GetILGenerator(); removeIl.Emit(OpCodes.Ldarg_0); removeIl.Emit(OpCodes.Ldarg_0); removeIl.Emit(OpCodes.Ldfld, eventField); removeIl.Emit(OpCodes.Ldarg_1); removeIl.EmitCall(OpCodes.Call, typeof(Delegate).GetMethod("Remove", new[] { typeof(Delegate), typeof(Delegate) }), null); removeIl.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler)); removeIl.Emit(OpCodes.Stfld, eventField); removeIl.Emit(OpCodes.Ret); MethodInfo miRemoveEvent = typeof(INotifyPropertyChanged).GetMethod("remove_PropertyChanged"); tb.DefineMethodOverride(mbEV, miRemoveEvent); eb.SetRemoveOnMethod(mbEV); mbEV = tb.DefineMethod("add_PropertyChanged", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual , null, new[] { typeof(PropertyChangedEventHandler) }); mbEV.SetImplementationFlags(eventMethodFlags); var addIl = mbEV.GetILGenerator(); addIl.Emit(OpCodes.Ldarg_0); addIl.Emit(OpCodes.Ldarg_0); addIl.Emit(OpCodes.Ldfld, eventField); addIl.Emit(OpCodes.Ldarg_1); addIl.EmitCall(OpCodes.Call, typeof(Delegate).GetMethod("Combine", new[] { typeof(Delegate), typeof(Delegate) }), null); addIl.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler)); addIl.Emit(OpCodes.Stfld, eventField); addIl.Emit(OpCodes.Ret); MethodInfo miAddEvent = typeof(INotifyPropertyChanged).GetMethod("add_PropertyChanged"); tb.DefineMethodOverride(mbEV, miAddEvent); eb.SetAddOnMethod(mbEV); //-*-*-*-*-*-*-*-*- MethodBuilder mbRaisePropertyChanged = tb.DefineMethod("RaisePropertyChanged", MethodAttributes.Virtual, null, new Type[] { typeof(string) }); var RaiseIl = mbRaisePropertyChanged.GetILGenerator(); System.Reflection.Emit.Label RaiseIlExitLabel = RaiseIl.DefineLabel(); RaiseIl.Emit(OpCodes.Ldarg_0); RaiseIl.Emit(OpCodes.Ldfld, eventField);//if RaiseIl.Emit(OpCodes.Ldnull); RaiseIl.Emit(OpCodes.Ceq); RaiseIl.Emit(OpCodes.Brtrue, RaiseIlExitLabel);//endif RaiseIl.Emit(OpCodes.Pop); RaiseIl.Emit(OpCodes.Ldarg_0); RaiseIl.Emit(OpCodes.Ldfld, eventField); RaiseIl.Emit(OpCodes.Ldarg_0); RaiseIl.Emit(OpCodes.Ldarg_1); RaiseIl.Emit(OpCodes.Newobj, typeof(PropertyChangedEventArgs).GetConstructor(new[] { typeof(string) })); RaiseIl.EmitCall(OpCodes.Callvirt, typeof(PropertyChangedEventHandler).GetMethod("Invoke"), null); RaiseIl.Emit(OpCodes.Nop); RaiseIl.Emit(OpCodes.Nop); RaiseIl.MarkLabel(RaiseIlExitLabel); RaiseIl.Emit(OpCodes.Ret); //*-*-*-*-*-*-*-*-*-- //Der RaisePropertyChangedaufruf im setter MethodBuilder setPropMthdBldr = _tb.DefineMethod("set_" + _propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { _propertyType }); ILGenerator setIl = setPropMthdBldr.GetILGenerator(); System.Reflection.Emit.Label exitSet = setIl.DefineLabel(); setIl.Emit(OpCodes.Ldarg_0); setIl.Emit(OpCodes.Ldarg_1); setIl.Emit(OpCodes.Stfld, fieldBuilder); /*INotifyPropertyChanged aufruf*/ setIl.Emit(OpCodes.Newobj, typeof(PropertyChangedEventArgs).GetConstructor(new[] { typeof(string) })); setIl.Emit(OpCodes.Ldstr, _propertyName); setIl.EmitCall(OpCodes.Callvirt, typeof(PropertyChangedEventHandler).GetMethod("Invoke"), null); setIl.Emit(OpCodes.Nop); setIl.MarkLabel(exitSet); setIl.Emit(OpCodes.Ret);
- Bearbeitet Robin4444 Montag, 31. März 2014 10:26
Antworten
-
Schau Dir mal folgende Links an : Link 1 & Link 2 .
Gruß,
Ciprian
Ciprian Bogdan, MICROSOFT
Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip„Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.
- Als Antwort markiert Robin4444 Mittwoch, 9. April 2014 07:22