Search code examples
c#.neteventsdelegatesobject-initializers

Assigning events in object initializer


Why isn't it possible to assign events along with properties in object initializers in C#? It seems to be so natural to do so.

var myObject = new MyClass()
     {
        Property = value,
        Event1 = actor,
        // or
        Event2 += actor
     };  

Or is there some trick that I don't know of?


Solution

  • As far the external contract is concerned, an event doesn't have a setter, only add and remove methods - subscribers can register and unregister from the event, and the publishing object decides when to invoke the callbacks by 'raising' the event. Consequently, the idea of "assigning an event", in general, is meaningless.

    However, when you declare an event in a class, the C# compiler provides you with what is really a convenience-feature: when you don't provide your own implementation, it creates a private, backing delegate-field for you, along with the appropriate add / remove implementations . This allows you to "set the event" (really the backing field) within the class, but not outside it. To understand this, consider:

    public class Foo
    {
        // implemented by compiler
        public event EventHandler MyEvent;
    
        public static Foo FooFactory(EventHandler myEventDefault)
        {
           // setting the "event" : perfectly legal
           return new Foo { MyEvent = myEventDefault }; 
        }
    }
    
    public class Bar
    {
        public static Foo FooFactory(EventHandler myEventDefault)
        {
            // meaningless: won't compile
            return new Foo { MyEvent = myEventDefault };
        }
    }
    
    
    public class Baz
    {
        // custom implementation
        public event EventHandler MyEvent
        {      
            add { }  // you can imagine some complex implementation here
            remove { } // and here
        }
    
        public static Baz BazFactory(EventHandler myEventDefault)
        {
            // also meaningless: won't compile
            return new Baz { MyEvent = myEventDefault };
        }
    }