Ricerca…


Osservazioni

Il processo di risoluzione del sovraccarico è descritto nella specifica C # , sezione 7.5.3. Rilevanti sono anche le sezioni 7.5.2 (inferenza del tipo) e 7.6.5 (espressioni di invocazione).

Come funziona la risoluzione di sovraccarico verrà probabilmente modificato in C # 7. Le note di progettazione indicano che Microsoft distribuirà un nuovo sistema per determinare quale metodo è migliore (in scenari complicati).

Esempio di sovraccarico di base

Questo codice contiene un metodo sovraccarico denominato Hello :

class Example
{
    public static void Hello(int arg)
    {
        Console.WriteLine("int");
    }
 
    public static void Hello(double arg)
    {
        Console.WriteLine("double");
    }
 
    public static void Main(string[] args) 
    {
        Hello(0);
        Hello(0.0);
    }
}

Quando viene chiamato il metodo Main , verrà stampato

int
double

In fase di compilazione, quando il compilatore trova il metodo call Hello(0) , trova tutti i metodi con il nome Hello . In questo caso, ne trova due. Quindi cerca di determinare quale dei metodi è migliore . L'algoritmo per determinare quale metodo è migliore è complesso, ma in genere si riduce a "generare il minor numero possibile di conversioni implicite".

Pertanto, nel caso di Hello(0) , non è necessaria alcuna conversione per il metodo Hello(int) ma è necessaria una conversione numerica implicita per il metodo Hello(double) . Quindi, il primo metodo è scelto dal compilatore.

Nel caso di Hello(0.0) , non esiste alcun modo per convertire implicitamente 0.0 in un int , quindi il metodo Hello(int) non è nemmeno considerato per la risoluzione di sovraccarico. Rimane solo il metodo e quindi viene scelto dal compilatore.

"params" non è espanso, se non necessario.

Il seguente programma:

class Program
{
    static void Method(params Object[] objects)
    {
        System.Console.WriteLine(objects.Length);
    }   
    static void Method(Object a, Object b)
    {
        System.Console.WriteLine("two");
    }
    static void Main(string[] args)
    {
        object[] objectArray = new object[5];

        Method(objectArray);
        Method(objectArray, objectArray);
        Method(objectArray, objectArray, objectArray);
    }
}

stamperà:

5
two
3

Il Method(objectArray) expression call Method(objectArray) potrebbe essere interpretato in due modi: un singolo argomento Object che capita di essere un array (quindi il programma emetterebbe 1 perché sarebbe il numero di argomenti, o come una matrice di argomenti, dato nel forma normale, come se il metodo Method non avesse i params della parola chiave In queste situazioni, la forma normale, non espansa ha sempre la precedenza, quindi il programma emette 5 .

Nella seconda espressione, Method(objectArray, objectArray) , sono applicabili sia la forma espansa del primo metodo che il secondo metodo tradizionale. Anche in questo caso, le forme non espanse hanno la precedenza, quindi il programma ne stampa two .

Nella terza espressione, Method(objectArray, objectArray, objectArray) , l'unica opzione è utilizzare la forma espansa del primo metodo, quindi il programma stampa 3 .

Passando null come uno degli argomenti

Se hai

void F1(MyType1 x) {
    // do something
}

void F1(MyType2 x) {
    // do something else
}

e per qualche motivo devi chiamare il primo overload di F1 ma con x = null , quindi fare semplicemente

F1(null);

non verrà compilato poiché la chiamata è ambigua. Per contrastare ciò che puoi fare

F1(null as MyType1);


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow