2010-04-06 13 views
8

Lassen Sie uns einen folgenden vereinfachten Beispiel haben:C# überladen mit Generics: Fehler oder Feature?

void Foo<T>(IEnumerable<T> collection, params T[] items) 
{ 
    // ... 
} 

void Foo<C, T>(C collection, T item) 
    where C : ICollection<T> 
{ 
    // ... 
} 

void Main() 
{ 
    Foo((IEnumerable<int>)new[] { 1 }, 2); 
} 

Compiler sagt:

Der Typ 'System.Collections.Generic.IEnumerable' nicht als Typ-Parameter 'C' in der generischen Art verwendet werden können, oder Methode 'UserQuery.Foo (C, T)'. Es gibt keine implizite Referenzkonvertierung von 'System.Collections.Generic.IEnumerable' zu 'System.Collections.Generic.ICollection'.

Wenn ich Main zu ändern:

void Main() 
{ 
    Foo<int>((IEnumerable<int>)new[] { 1 }, 2); 
} 

wird es ok arbeiten. Warum Compiler wählt nicht die richtige Überlastung?

+0

gibt es wirklich keine Konvertierung zwischen IEnumerable und ICollection. – nothrow

+1

@Yossarian: zwei Dinge. Erstens gibt es eine explizite Konvertierung. Sie wollen sagen "es gibt wirklich keine implizite Referenzkonvertierung". Zweitens ist die Frage nicht "Warum bekomme ich einen Fehler" keine implizite Umwandlung "?" Zweitens stellt sich die Frage, "warum wählt der Überladungsauflösungsalgorithmus einen Kandidaten mit exakter Übereinstimmung aus, der ungültig ist, anstatt den gültigen, aber schlechteren Kandidaten auszuwählen, der nicht genau übereinstimmt?" –

Antwort

15

Ihre Frage wird hier beantwortet.

http://blogs.msdn.com/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx

Bitte lesen Sie auch die rund eine Million Kommentare mir zu sagen, dass ich für einige interessante Zusatz Kommentar zu diesem Thema falsch bin.

+0

Ok. Vielen Dank für die schnelle Antwort :) Ich muss immer lange warten, bis ich die Antwort annehmen kann :) –

+0

Ich wusste, dass ich diesen Artikel gelesen habe und ich suchte danach ... aber offensichtlich kennen Sie Ihren Blog besser als ich und Finde die Artikel schneller - was ziemlich fair ist ... ^^ – tanascius

2

Meine Vermutung ist, dass der Compiler die beste Übereinstimmung vor der Verwendung der generischen Constraint wählt. In Ihrem Beispiel ist die Methode mit der Einschränkung vorzuziehen, weil sie keinen letzten Parameter params hat.

Bearbeiten - Eric Lippert bestätigt dies in seiner Antwort.

+0

Ja. Danke dir auch:) –