2015-11-05 20 views
8

Ho una variabile di tipo Func<dynamic> e sto cercando di assegnargli un valore. Se ho assegnarlo a un metodo che restituisce un tipo di valore (ad esempio int), ottengo l'erroreImpossibile assegnare metodi che restituiscono tipi di valori a Func <dynamic>

'int MethodName()' ha il tipo di ritorno sbagliato

Se mi avvolgo il metodo in una chiamata lambda, tuttavia, funziona bene. Anche i metodi che restituiscono tipi di riferimento sembrano funzionare correttamente.

private string Test() 
{ 
    return ""; 
} 

private int Test2() 
{ 
    return 0; 
} 

Func<dynamic> f = Test;   // Works 
Func<dynamic> g = Test2;   // Does not 
Func<dynamic> h =() => Test2(); // Works 

Cosa c'è che non va nel caso di assegnazione diretta?

+0

Non è solo "dinamico". Se si modifica 'Func ' a 'Func ' si ottiene lo stesso errore, e penso che sia perché l'operazione di boxe verrebbe introdotta indirettamente, e il compilatore non è ok, ma non riesco a trovare nulla nelle specifiche che descriverebbe questa situazione. – MarcinJuraszek

+0

@MarcinJuraszek Dalle specifiche sulla compatibilità dei delegati, "Per ciascun parametro di valore (un parametro senza alcun modificatore di rift o di out), una conversione di identità (§6.1.1) o una conversione di riferimento implicita (§6.1.6) esiste dal tipo di parametro in D al tipo di parametro corrispondente in M. " Esiste una conversione implicita in questo caso, ma non è un'identità o una conversione di riferimento. – Servy

risposta

4

Questo non ha nulla a che fare con dynamic o delegate TResult Func<out TResult>(). Si vedrà lo stesso comportamento in questo codice:

interface I<out T> { } 
class C<T> : I<T> { } 
... 
I<int> a = new C<int>(); 
I<string> b = new C<string>(); 
I<object> x = a; // compiler error 
I<object> y = b; // no compiler error 

Per qualche ragione, i tipi di valore come int verranno automaticamente cast object o dynamic, ma I<int> volontà non automaticamente cast I<object> o I<dynamic>. Non riesco a trovare dove è specificato nel riferimento alla lingua.

Il motivo Func<dynamic> h =() => Test2(); funziona nel codice è perché richiede solo da trasmettere a dynamic implicitamente, che va bene. Non richiede Func<int> di trasmettere implicitamente a Func<dynamic>.

+0

Spiegazione completa di Eric Lippert: http://stackoverflow.com/a/4098434/1828879 –