2015-11-05 7 views
8

Ich habe eine Variable vom Typ Func<dynamic> und ich versuche, einen Wert zuzuweisen. Wenn ich es auf ein Verfahren zuweisen, die einen Wert Typ zurückgibt (zB int), erhalte ich die FehlerKann keine Methoden zuweisen, die Werttypen zu Func zurückgeben <dynamic>

‚int Method()‘ hat den falschen Rückgabetyp

Wenn ich die Methode umwickeln Ein Lambda-Call funktioniert jedoch einwandfrei. Auch Methoden, die Referenztypen zurückgeben, scheinen zu funktionieren.

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 

Was stimmt nicht mit dem Fall der direkten Zuweisung?

+0

Es ist nicht nur 'dynamisch'. Wenn Sie Ihre 'Func ' zu 'Func ' ändern, erhalten Sie den gleichen Fehler, und ich denke, es ist, weil Box-Betrieb indirekt eingeführt werden würde, und Compiler ist nicht in Ordnung, aber ich kann nichts in der Spezifikation finden würde diese Situation beschreiben. – MarcinJuraszek

+0

@MarcinJuraszek Aus den Spezifikationen zur Delegiertenkompatibilität: "Für jeden Wertparameter (ein Parameter ohne Ref- oder Out-Modifikator) existiert eine Identitätskonvertierung (§6.1.1) oder eine implizite Referenzkonvertierung (§6.1.6) aus dem Parametertyp in D zu dem entsprechenden Parametertyp in M. In diesem Fall gibt es eine implizite Konvertierung, es handelt sich jedoch nicht um eine Identitäts- oder Referenzkonvertierung. – Servy

Antwort

4

Dies hat nichts mit dynamic oder delegate TResult Func<out TResult>() zu tun. Sie werden das gleiche Verhalten in diesem Code sehen:

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 

Aus irgendeinem Grund Werttypen wie int automatisch zu gieße object oder dynamic, aber I<int> wird nicht automatisch cast I<object> oder I<dynamic>. Ich kann nicht finden, wo in der Sprachreferenz dies angegeben ist.

Der Grund Func<dynamic> h =() => Test2(); funktioniert in Ihrem Code ist, weil es nur int implizit zu dynamic implizit erfordert, was in Ordnung ist. Es ist nicht erforderlich, Func<int> implizit auf Func<dynamic> zu übertragen.

+0

Vollständige Erklärung von Eric Lippert: http://Stackoverflow.com/a/4098434/1828879 –