Search code examples
c#eventsgarbage-collectionweak-references

Does empty add/remove event definition prevent references?


I'm implementing an interface which defines an event which I don't need/want, but I want to avoid keeping unwitting subscribers 'alive'.

I think that if I define the event explicitly, this should suffice, but will the compiler add code in there and thwart my plans?

public event EventHandler CanExecuteChanged
{
    add { }
    remove { }
}

Context: I've had problems with MVVMLight RelayCommand because it uses WeakReference, and apparently I have too much indirection in my code and I'm losing commands. So I want to implement my own CanAlwaysExecuteCommand, for which I don't need the event.


Solution

  • Yes this should work. I use the same trick if an interface forces INotifyPropertyChanged and some of the implementations are immutable.

    But I wasn't sure so I tested it using this class:

    public class Foo : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged
        {
            add { }
            remove { }
        }
    }
    

    The corresponding IL-Code for the event implementation (shown by dotPeek) is:

    .method public final hidebysig virtual newslot specialname instance void 
      add_PropertyChanged(
        class [System]System.ComponentModel.PropertyChangedEventHandler 'value'
      ) cil managed 
    {
      .maxstack 8
    
      // [77 17 - 77 18]
      IL_0000: nop          
    
      // [77 19 - 77 20]
      IL_0001: ret          
    
    } // end of method Foo::add_PropertyChanged
    
    .method public final hidebysig virtual newslot specialname instance void 
      remove_PropertyChanged(
        class [System]System.ComponentModel.PropertyChangedEventHandler 'value'
      ) cil managed 
    {
      .maxstack 8
    
      // [78 20 - 78 21]
      IL_0000: nop          
    
      // [78 22 - 78 23]
      IL_0001: ret          
    
    } // end of method Foo::remove_PropertyChanged
    
    .event [System]System.ComponentModel.PropertyChangedEventHandler PropertyChanged
    {
      .addon instance void ConsoleApplication1.Foo::add_PropertyChanged(class [System]System.ComponentModel.PropertyChangedEventHandler) 
      .removeon instance void ConsoleApplication1.Foo::remove_PropertyChanged(class [System]System.ComponentModel.PropertyChangedEventHandler) 
    } // end of event Foo::PropertyChanged