Asignación de eventos en inicializador de objetos

¿Por qué no es posible asignar eventos junto con propiedades en inicializadores de objetos en C #? Parece ser tan natural hacerlo.

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

¿O hay algún truco que no conozco?

En lo que respecta al contrato externo, un evento no tiene un configurador, solo add y remove métodos : los suscriptores pueden registrarse y remove registro del evento, y el objeto de publicación decide cuándo invocar las devoluciones de llamada al “elevar” el evento. En consecuencia, la idea de “asignar un evento”, en general, no tiene sentido.

Sin embargo, cuando declara un evento en una clase, el comstackdor de C # le proporciona lo que realmente es una característica de conveniencia: cuando no proporciona su propia implementación, crea un campo de delegado privado de respaldo para usted, junto con el Añadir / eliminar implementaciones apropiadas. Esto le permite “configurar el evento” (en realidad, el campo de respaldo) dentro de la clase, pero no fuera de él. Para entender esto, considere:

 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 }; } } 

Solo puede usar los operadores += o -+ para un evento fuera de su clase de propietario.

 public class Data { public event EventHandler OnSave = (s,e) => { //do something important! }; public void Save() { OnSave(this,null); //do save } } //outside the class Data data = new Data { OnSave = null }; //compile error data.OnSave = SomeMethodElse; //compile error data.OnSave += MyCustomActionsOnSave; //ok data.Save(); 

No puede eliminar la acción OnSave definida en la clase. Solo puede agregar / eliminar sus propias acciones de OnSave fuera de la clase. Si elimina la palabra clave del event , OnSave ya no será un evento, sino un delegado ordinario. Entonces puedes hacer cualquier cosa, incluyendo la asignación de valor fuera de la clase.

Esto no hizo que C # 6 o C # 7 (desde la pregunta original), sin embargo, no se ha decidido en contra. Hay un problema en GitHub que rastrea la propuesta de idioma. Puede votar por él allí, así como seguir los enlaces a las discusiones anteriores sobre la función.

https://github.com/dotnet/csharplang/issues/307

Si desea ver esta función, agregue un pulgar hacia arriba al problema para ayudar a boost su visibilidad.

La syntax propuesta es:

 var timer = new DispatcherTimer { Tick += delegate {}, Interval = TimeSpan.FromSeconds(1d), };