2015-02-13 10 views
6

Dire che ho il seguente metodo:C# inferenza di tipo non riesce con metodi che contengono i parametri di default

static int MethodWithDefaultParameters(int a, int b=0, int c=1) 
{ 
    return a + b + c; 
} 

E poi io uso questo metodo in una query LINQ in questo modo:

Enumerable.Range(1,10).Select(MethodWithDefaultParameters); 

questo viene a mancare con :

Errore 1 Gli argomenti tipo per il metodo 'System.Linq.Enumerable.Select (System.Collections.Generic.IEnumerable, System.Func)' non possono essere infe rred dall'uso. Prova a specificare esplicitamente gli argomenti del tipo.

Naturalmente, posso ovviare a questo con l'inserimento di un lambda che inoltra la chiamata di funzione come questa:

Enumerable.Range(1,10).Select(i => MethodWithDefaultParameters(i)); 

Ma la mia domanda è: perché l'inferenza di tipo fallire? Per quanto posso dire, non dovrebbe essere ambiguo in quanto esiste solo una variante della funzione che soddisfa la variabile di input.

risposta

10

Esistono due sovraccarichi per Select(). Uno che prende come secondo parametro (cioè il delegato) uno Func<TSource, TResult> e uno che prende uno Func<TSource, int, TResult>. Cioè una firma del metodo con uno o due parametri.

Il tuo metodo non soddisfa nessuno dei due. Anche con i valori predefiniti, ha ancora tre parametri. I parametri predefiniti sono un compilazione di compilazione e devono essere forniti nel sito di chiamata. Non vengono compilati in fase di esecuzione tramite una chiamata a un'istanza delegato.

Quindi, in realtà, il tuo intervento è uno dei due modi più adeguati per risolvere il problema. L'altro sarebbe per implementare i parametri di default in modo diverso (vale a dire "vecchia scuola" :)):

static int MethodWithDefaultParameters(int a) 
{ 
    return MethodWithDefaultParameters(a, 0, 1); 
} 

static int MethodWithDefaultParameters(int a, int b, int c) 
{ 
    return a + b + c; 
} 

quindi è possibile utilizzare MethodWithDefaultParameters nella chiamata a Select() direttamente, come il compilatore troverà il sovraccarico di un solo parametro questo è compatibile con uno dei sovraccarichi dello Select().

+0

Ottima risposta! – Enigmativity

+0

Aha, per quanto riguarda il motore di inferenza del tipo, la firma per MethodWithDefaultParameters sarà sempre con tre argomenti, cioè non vedrà mai una versione con un solo parametro. Grazie per la spiegazione! – Thaddeus

Problemi correlati