Frage

Ich habe gerade bemerkt ein seltsames Verhalten mit Überladungsauflösung.

Nehmen wir an, ich die folgende Methode haben:

public static void DoSomething<T>(IEnumerable<T> items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(IEnumerable<T> items)");
}

Nun, ich weiß, dass diese Methode wird oft mit einer kleinen Anzahl von expliziten Argumenten aufgerufen werden, so der Einfachheit halber füge ich diese Überlastung:

public static void DoSomething<T>(params T[] items)
{
    // Whatever

    // For debugging
    Console.WriteLine("DoSomething<T>(params T[] items)");
}

Jetzt versuche ich, diese Methoden zu nennen:

var items = new List<string> { "foo", "bar" };
DoSomething(items);
DoSomething("foo", "bar");

Aber in beiden Fällen ist die Überlastung mit params genannt. Ich würde die IEnumerable<T> Überlastung zu erwarten im Fall eines List<T> genannt werden, weil es eine bessere Übereinstimmung (zumindest für mich) scheint.

Ist dieses Verhalten normal? Könnte jemand erklären? Ich konnte keine klaren Informationen über die in MSDN-Dokumentation finden ... Was die Überladungsauflösung Regeln hier beteiligt sind?

War es hilfreich?

Lösung

Abschnitt 7.4.3 der C # 3.0-Spezifikation ist das entsprechende Bit hier. Grundsätzlich ist der Parameter-Array wird erweitert, so dass Sie vergleichen:

public static void DoSomething<T>(T item)

und

public static void DoSomething<T>(IEnumerable<T> item)

Die T für das erste Spiel wird gefolgert werden List<string> und die T für das zweite Spiel wird gefolgert string werden.

; In dem ersten es List<string> ist zu List<string> -

Jetzt die Konvertierungen für Argument Parametertyp beteiligt betrachten im zweiten ist es List<string> IEnumerable<string>. Die erste Umwandlung ist besser als die zweite durch die Regeln in 7.4.3.4.

Das eingängig Bit ist die Typinferenz. Wenn Sie, dass aus der Gleichung nehmen, wird es funktionieren, wie Sie es erwarten:

var items = new List<string> { "foo", "bar" };
DoSomething<string>(items);
DoSomething<string>("foo", "bar");

An diesem Punkt gibt es nur einen gültigen Funktionselement in jedem Aufruf.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top