2010-06-14 14 views
6

Następujący kod nie kompilacji (error CS0123: No overload for 'System.Convert.ToString(object)' matches delegate 'System.Converter<T,string>')W jaki sposób rozdzielczość przeciążenia grupy metod różni się od rozdzielczości przeciążenia wywołania metody?

class A<T> { 
    void Method(T obj) { 
     Converter<T, string> toString = Convert.ToString; 

     // this doesn't work either (on .NET 4): 
     Converter<object, string> toString2 = Convert.ToString; 
     Converter<T, string> toString3 = toString2;    
    } 
} 

to jednak,:

class A<T> { 
    void Method(T obj) { 
     // o is a T, and Convert.ToString(o) is using 
     // string Convert.ToString(object o) 

     Converter<T, string> toString = o => Convert.ToString(o); 
    } 
} 

C# 4, CO/przeciwwskazane wariant uczestników może być przypisany do siebie i Uczestnicy mogą być tworzone z metod co/przeciw-wariantowych, więc metoda ToString(object) może być używana jako Converter<T, string>, ponieważ T jest zawsze gwarantowana do konwertowania na object.

Pierwszy przykład (rozdzielczość grupy przeładowań) powinien znaleźć jedyną stosowną metodę string Convert.ToString(object o), taką samą jak rozdzielczość przeładowania metody. Dlaczego metoda method group & wywołuje zbyt wysoką rozdzielczość wywoływania różnych wyników?

Odpowiedz

3

Ma to związek z faktem, że wariancja nie stosuje się do typów wartości, więc jeśli ograniczyć T jak where T : class dostać wariancji na T i pierwszy fragment kodu zostanie skompilowany.

Z Covariance and Contravariance FAQ:

Wariancja jest obsługiwana tylko wtedy, gdy parametr typu to rodzaj odniesienia. Odchylenie nie jest obsługiwane dla typów wartości .

+0

Dokładniej, to nie działa dla nieograniczonego "T", ponieważ _ __ może to być typ wartości. – thecoop

0

Drugi kod kompiluje ponieważ owywodzi z object, więc oczywiście można wywołać metodę, która pobiera object jako wejście z dowolny typu parametru.

Typy delegatów są jednak następujące: nie są równe. Chyba że T jest object sygnatury metody nie pasują. Jeśli, powiedzmy, T jest int, masz Converter<int, string>, który nie jest taki sam jak Converter<object, string. Są to dwa różne typy różnych typów.

Uderzasz w problemy związane z brakiem współdziałania/contra-wariancji w C# 3.0. Powinno być lepiej w C# 4.

+0

To jest .NET 4. Zaktualizowałem moje pytanie – thecoop

Powiązane problemy