2010-02-18 10 views
14

Sono in grado di assegnare un metodo M per delegare l'oggetto d con un tipo di parametro meno specifico, ma quando voglio assegnare un metodo anonimo con lo stesso la firma come metodo M a d, viene visualizzato un errore.Impossibile assegnare a delegare un metodo anonimo con un tipo di parametro meno specifico

Perché è quello?

class derivedEventArgs : EventArgs { } 

delegate void newDelegate(object o, derivedEventArgs e); 

static void Main(string[] args) 
{ 
    newDelegate d = M; // ok 
       d = (object o, EventArgs e) => { }; // error 
} 

public static void M(object o, EventArgs e) { } 
+2

Hai certamente alcune convenzioni di denominazione interessanti in corso ... –

risposta

15

Jared è ovviamente corretto che questo è di progettazione.

Il motivo di tale progettazione è che nel caso di conversione del metodo controverso, potresti avere un metodo che non hai scritto e assegnarlo a una variabile delegata che non hai scritto. Non controlli i tipi. Quindi andiamo un po 'meglio con te e lasciamo che i parametri corrispondano in modo controverso e che i tipi di ritorno corrispondano in modo covariante.

Nella conversione da lambda a delegato, è do controllare la cosa assegnata. Non c'è nulla fermando di fare una corrispondenza esatta nei tipi di parametri e quindi noi richiedere a. Qui non sono consentiti fudging.

+0

Grandi risposte. Grazie per avermi aiutato – AspOnMyNet

16

Questo è descritto nella sezione 6.5 delle specifiche del linguaggio C#. Se si digitano in modo esplicito i parametri di una funzione anonima, devono corrispondere sia al tipo che ai modificatori per essere firme compatibili.

In particolare, un tipo delegato D è compatibile con una funzione anonima F fornito

...

Se F ha una lista di parametri in modo esplicito digitato, ogni parametro D ha lo stesso tipo e modificatori come parametro corrispondente in F.

+1

+1 risposta molto veloce. –

2

Mentre si ottiene la risposta, fornirò una soluzione alternativa se è richiesto. Di ', tutto quello che hai è un delegato della firma (object, EventArgs), nel qual caso si desidera convertire al vostro tipo newDelegate, si potrebbe fare:

SomeDelegate p = (object o, EventArgs e) => { }; //comes from somewhere 
NewDelegate d = (o, e) => p(o, e); //can rewrite like this 

alternativa con i generici e (contra) caratteristica varianza di delegati generico, è possibile fallo con un tipo di delegato:

delegate void NewDelegate<in T>(object o, T e) where T : EventArgs; 

//then 
NewDelegate<EventArgs> p = (object o, EventArgs e) => { }; //comes from somewhere 
NewDelegate<DerivedEventArgs> d = p; //straightforward assignable - contravariance 
Problemi correlati