2010-10-22 16 views
17

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

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

¿O hay algún truco que yo desconozca?

+0

Parece que esta característica va a ser añadido en la próxima versión de idioma http://roslyn.codeplex.com/wikipage?title=Language+Feature+Status – Zarat

+0

Si usted todavía está interesado, por favor mire mi sugerencia aquí: http://stackoverflow.com/questions/24951619/add-event-handler-during-object-initialization/37994490#37994490 –

Respuesta

5

En lo que respecta al contrato externo se trate, un evento no tiene un setter, sólo add y removemétodos - los suscriptores pueden registrar y eliminar del evento, y la publicación de objeto decide cuándo invocar las devoluciones de llamada "elevando" el evento. En consecuencia, la idea de "asignar un evento", en general, no tiene sentido.

Sin embargo, cuando se declara un evento en una clase, el compilador de C# le proporciona lo que es realmente una conveniencia-función: cuando usted no proporciona su propia implementación, se crea un privada, retrocediendo delegado de campo para ti, junto con las implementaciones de agregar/eliminar apropiadas. Esto le permite "establecer el evento" (realmente el campo de respaldo) dentro de la clase, pero no fuera de ella. 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 }; 
    } 
} 
+5

Esto no tiene nada que ver con la restricción. Las propiedades tienen métodos setter y campos de respaldo privados, sin embargo, el inicializador de objetos funciona bien con eso. –

3

Solo puede usar los operadores += o -+ en 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 se puede eliminar la acción OnSave definida en la clase. Solo puede agregar/eliminar sus propias acciones OnSave fuera de la clase. Si elimina la palabra clave event, el OnSave ya no será un evento, sino un delegado común. Entonces puede hacer cualquier cosa, incluso asignar valor fuera de la clase.

+0

Él ES (querer) usar '+ =' . –

1

Esto no hizo que C# 6 o C# 7 (ya que la pregunta original), sin embargo no se ha decidido en contra. Hay un problema en GitHub que rastrea la propuesta de idioma. Puede votar allí, y seguir los enlaces a la discusión previa sobre la función.

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

Si desea ver esta función, añada un pulgar hacia arriba con el tema para ayudar a elevar su visibilidad.

La sintaxis propuesta es:

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