title: Implementing INotifyPropertyChanged with Reflection.Emit
body: <p>Using C#/.Net 4.0, I'm storing data in a BindingList where dataRow is being defined at run time via Reflection.Emit. (The structure of the incoming data varies and is defined by an external source.)
  After struggling a bit with my first foray into the world of reflection and IL, I have been able to create my dataRow fill it with values, fill my BindingList and display the result in a grid.
  I now am trying to implement the INotifyPropertyChanged interface and the PropertyChangedEventHandler when changes are made to the data. Using <a href="http://grahammurray.wordpress.com/2010/04/13/dynamically-generating-types-to-implement-inotifypropertychanged/" rel="nofollow noreferrer">this</a> as a guide, I've got code that runs but it doesn't appear that the RaisePropertyChanged event is firing or it just isn't doing anything. When I compare my dynamic version with a normal/static version via ildasm.exe I see major differences in the remove_PropertyChanged and add_PropertyChanged methods.
  Could anyone provide some tips or examples of implementing the INotifyPropertyChanged interface via reflection.</p>
  
  <p>After further review it seems that the event field must be null so the PropertyChangedEventHandler is not getting called. I added some message boxes in the RaiseProprtyChanged method builder and I discovered that the equivalent of <strong>if (PropertyChanged != null)</strong> is returning zero/false, so nothing happens. If I change the OpCodes.Brtrue to OpCodes.Brfalse I get a "Object reference not set to an instance of an object" message.
  It feels like I missing something simple but I can't find it.</p>
  
  <pre><code>            //implement IINotifyPropertyChanged interface
          tb.AddInterfaceImplementation(typeof(INotifyPropertyChanged));
  
          //property changed event handler
          FieldBuilder eventField = tb.DefineField("PropertyChanged", typeof(PropertyChangedEventHandler), FieldAttributes.Private);
  
          EventBuilder eb = tb.DefineEvent("PropertyChanged", EventAttributes.None, typeof(PropertyChangedEventHandler));
  
          MethodBuilder mbEV = tb.DefineMethod("remove_PropertyChanged", MethodAttributes.Public |
              MethodAttributes.SpecialName | MethodAttributes.NewSlot |
              MethodAttributes.HideBySig | MethodAttributes.Virtual |
              MethodAttributes.Final, null, new[] { typeof(PropertyChangedEventHandler) });
  
          MethodImplAttributes eventMethodFlags = MethodImplAttributes.Managed; //| MethodImplAttributes.Synchronized;
          mbEV.SetImplementationFlags(eventMethodFlags);
          il = mbEV.GetILGenerator();
          il.Emit(OpCodes.Ldarg_0);
          il.Emit(OpCodes.Ldarg_0);
          il.Emit(OpCodes.Ldfld, eventField);
          il.Emit(OpCodes.Ldarg_1);
          il.EmitCall(OpCodes.Call, typeof(Delegate).GetMethod("Remove", new[] { typeof(Delegate), typeof(Delegate) }), null);
          il.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
          il.Emit(OpCodes.Stfld, eventField);
          il.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.NewSlot |
              MethodAttributes.HideBySig | MethodAttributes.Virtual |
              MethodAttributes.Final, null, new[] { typeof(PropertyChangedEventHandler) });
  
          mbEV.SetImplementationFlags(eventMethodFlags);
          il = mbEV.GetILGenerator();
          il.Emit(OpCodes.Ldarg_0);
          il.Emit(OpCodes.Ldarg_0);
          il.Emit(OpCodes.Ldfld, eventField);
          il.Emit(OpCodes.Ldarg_1);
          il.EmitCall(OpCodes.Call, typeof(Delegate).GetMethod("Combine", new[] { typeof(Delegate), typeof(Delegate) }), null);
          il.Emit(OpCodes.Castclass, typeof(PropertyChangedEventHandler));
          il.Emit(OpCodes.Stfld, eventField);
          il.Emit(OpCodes.Ret);
          MethodInfo miAddEvent = typeof(INotifyPropertyChanged).GetMethod("add_PropertyChanged");
          tb.DefineMethodOverride(mbEV, miAddEvent);
          eb.SetAddOnMethod(mbEV);
  
          MethodInfo msgboxMethodInfo = typeof(System.Windows.Forms.MessageBox).GetMethod("Show", BindingFlags.Public | BindingFlags.Static, null, CallingConventions.Standard, new Type[] { typeof(String) }, null);
  
          MethodBuilder mbRaisePropertyChanged = tb.DefineMethod("RaisePropertyChanged", MethodAttributes.Virtual, null, new Type[] { typeof(string) });
          il = mbRaisePropertyChanged.GetILGenerator();
          System.Reflection.Emit.Label labelExit = il.DefineLabel();
          il.Emit(OpCodes.Ldarg_0);
          il.Emit(OpCodes.Ldfld, eventField);
          il.Emit(OpCodes.Ldnull);
          il.Emit(OpCodes.Ceq); //this is returning false
          il.Emit(OpCodes.Brtrue, labelExit);
          il.Emit(OpCodes.Nop); //I never get here
          il.Emit(OpCodes.Ldstr, "After If");
          il.EmitCall(OpCodes.Call, msgboxMethodInfo, null);
          il.Emit(OpCodes.Pop);
          il.Emit(OpCodes.Ldarg_0);
          il.Emit(OpCodes.Ldfld, eventField);
          il.Emit(OpCodes.Ldarg_0);
          il.Emit(OpCodes.Ldarg_1);
          il.Emit(OpCodes.Newobj, typeof(PropertyChangedEventArgs).GetConstructor(new[] { typeof(string) }));
          il.EmitCall(OpCodes.Callvirt, typeof(PropertyChangedEventHandler).GetMethod("Invoke"), null);
          il.Emit(OpCodes.Nop);
          il.Emit(OpCodes.Nop);
          il.MarkLabel(labelExit);
          il.Emit(OpCodes.Ret);
  </code></pre>