Domanda

Ho appena notato uno strano comportamento con risoluzione del sovraccarico.

Supponi di avere il seguente metodo:

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

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

Ora, so che questo metodo verrà spesso chiamato con un piccolo numero di argomenti espliciti, quindi per comodità aggiungo questo sovraccarico:

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

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

Ora provo a chiamare questi metodi:

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

Ma in entrambi i casi viene chiamato il sovraccarico con params. Mi sarei aspettato che il sovraccarico IEnumerable<T> fosse chiamato nel caso di un List<T>, perché sembra una corrispondenza migliore (almeno per me).

Questo comportamento è normale? Qualcuno potrebbe spiegarlo? Non sono riuscito a trovare chiare informazioni al riguardo nei documenti MSDN ... Quali sono le regole di risoluzione del sovraccarico coinvolte qui?

È stato utile?

Soluzione

La sezione 7.4.3 della specifica C # 3.0 è il bit rilevante qui. Fondamentalmente l'array di parametri è espanso, quindi stai confrontando:

public static void DoSomething<T>(T item)

e

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

Il T per la prima partita viene dedotto come List<string> e il string per la seconda partita viene dedotto come IEnumerable<string>.

Ora considera le conversioni coinvolte per argomento a tipo di parametro - nella prima è <=> a <=>; nel secondo è <=> a <=>. La prima conversione è migliore della seconda per le regole in 7.4.3.4.

Il bit controintuitivo è l'inferenza del tipo. Se lo elimini dall'equazione, funzionerà come previsto:

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

A quel punto, c'è solo un membro della funzione applicabile in ogni chiamata.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top