2015-11-05 14 views
8

Mam zmiennej typu Func<dynamic> i próbuję przypisać jej wartość. Gdybym przypisać go do metody, która zwraca typ wartości (np int), pojawia się błądNie można przypisać metod, które zwracają typy wartości do Func <dynamic>

„int MethodName()” ma złą powrotną typ

Gdybym zawinąć metodę w wywołanie lambda, jednak działa dobrze. Również metody zwracające typy odniesienia wydają się działać dobrze.

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 

Co jest nie tak w przypadku bezpośredniego przypisania?

+0

To nie jest po prostu "dynamiczny". Jeśli zmienisz 'Func ' na 'Func ' otrzymasz ten sam błąd i myślę, że to dlatego, że operacja boksu zostanie wprowadzona pośrednio, a kompilator nie jest z tym w porządku, ale nie mogę znaleźć niczego w specyfikacji, która opisałbym tę sytuację. – MarcinJuraszek

+0

@MarcinJuraszek Ze specyfikacji dotyczącej zgodności uczestnika "Dla każdego parametru wartości (parametru bez modyfikatora ref lub out), konwersja tożsamości (§ 6.1.1) lub niejawna konwersja referencyjna (§6.1.6) istnieje z typu parametru w D do odpowiedniego typu parametru w M. " Istnieje niejawna konwersja w tym przypadku, ale nie jest to konwersja tożsamości lub odniesienia. – Servy

Odpowiedz

4

Nie ma to nic wspólnego z dynamic lub delegate TResult Func<out TResult>(). widać to samo zachowanie w tym kodzie:

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 

Z jakiegoś powodu, typy wartości, takie jak int automatycznie rzutować na object lub dynamic, ale I<int> nie będzie automatycznie oddanych do I<object> lub I<dynamic>. Nie mogę znaleźć miejsca, w którym podano odnośnik do języka.

Powód, dla którego Func<dynamic> h =() => Test2(); działa w twoim kodzie, ponieważ wymaga on tylko int do nieotrzymania odlewania do dynamic, co jest w porządku. Nie wymaga on od użytkownika Func<int> rzucania do Func<dynamic> niejawnie.

+0

Pełne wyjaśnienie Eric Lippert: http://stackoverflow.com/a/4098434/1828879 –

Powiązane problemy