[c#] Perché aggiungere un metodo aggiunge una chiamata ambigua se non è coinvolta nell'ambiguità



1 Answers

Quale parte della specifica dice che dovrebbe essere così?

Sezione 7.5.3 (risoluzione di sovraccarico), insieme alle sezioni 7.4 (ricerca dei membri) e 7.5.2 (inferenza del tipo).

Nota in particolare la sezione 7.5.3.2 (membro della funzione migliore), che dice in parte "i parametri opzionali senza argomenti corrispondenti vengono rimossi dalla lista dei parametri" e "Se M (p) è un metodo non generico amd M (q) è un metodo generico, quindi M (p) è migliore di M (q). "

Tuttavia, non capisco abbastanza bene queste parti delle specifiche per sapere quali parti della specifica controllano questo comportamento, e tanto meno per giudicare se sia conforme.

Question

Ho questa classe

public class Overloaded
{
    public void ComplexOverloadResolution(params string[] something)
    {
        Console.WriteLine("Normal Winner");
    }

    public void ComplexOverloadResolution<M>(M something)
    {
        Console.WriteLine("Confused");
    }
}

Se lo chiamo in questo modo:

        var blah = new Overloaded();
        blah.ComplexOverloadResolution("Which wins?");

Scrive Normal Winner sulla console.

Ma, se aggiungo un altro metodo:

    public void ComplexOverloadResolution(string something, object somethingElse = null)
    {
        Console.WriteLine("Added Later");
    }

Ottengo il seguente errore:

La chiamata è ambigua tra i seguenti metodi o proprietà:> ' Overloaded.ComplexOverloadResolution(params string[]) ' e ' Overloaded.ComplexOverloadResolution<string>(string) '

Posso capire che l'aggiunta di un metodo potrebbe introdurre un'ambiguità di chiamata, ma è un'ambiguità tra i due metodi già esistenti (params string[]) e <string>(string) ! Chiaramente, nessuno dei due metodi coinvolti nell'ambiguità è il metodo appena aggiunto, perché il primo è un param, e il secondo è un generico.

è un insetto? Quale parte della specifica dice che dovrebbe essere così?




Se rimuovi i params dal tuo primo metodo, questo non succederebbe. Il primo e il terzo metodo hanno entrambe chiamate valide ComplexOverloadResolution(string) , ma se il primo metodo è public void ComplexOverloadResolution(string[] something) non ci sarà alcuna ambiguità.

Fornire valore per un object somethingElse = null parametro object somethingElse = null rende parametro opzionale e quindi non deve essere specificato quando si chiama quel sovraccarico.

Modifica: il compilatore sta facendo alcune cose pazzesche qui. Se sposti il ​​tuo terzo metodo in codice dopo il tuo primo, verrà segnalato correttamente. Quindi sembra che stia prendendo i primi due sovraccarichi e li segnali, senza verificare quello corretto.

"ConsoleApplication1.Program.ComplexOverloadResolution (params string [])" e "ConsoleApplication1.Program.ComplexOverloadResolution (string, object)"

Edit2: nuova scoperta. La rimozione di qualsiasi metodo dai tre precedenti non produrrà alcuna ambiguità tra i due. Quindi sembra che il conflitto appaia solo se ci sono tre metodi presenti, indipendentemente dall'ordine.




Related