2013-11-03 11 views
7

Perché non è possibile effettuare le seguenti operazioni:Uso dei parametri opzionali e denominati con l'azione e Func delegati

Func<int, int, int> sum = delegate(int x, int y = 20) { return x + y; }; 

Action<string, DateTime> print = 
    delegate(string message, DateTime datetime = DateTime.Now) 
    { 
     Console.WriteLine(message); 
    }; 

sum(x: 20, y: 40); 
print(datetime: DateTime.Now, message: "Hello"); 

caso con parametri solo di nome:

Func<int, int, int> sum = delegate(int x, int y) { return x + y; }; 

Action<string, DateTime> print = 
    delegate(string message, DateTime datetime) 
    { 
     Console.WriteLine("{0} {1}", message, datetime); 
    }; 

Console.WriteLine(sum(y: 20, x: 40)); 
print(datetime: DateTime.Now, message: "Hello"); 

caso con solo i parametri opzionali:

Func<int, int, int> sum = delegate(int x, int y = 20) { return x + y; }; 

Action<string , DateTime> print = 
    delegate(string message, DateTime datetime = DateTime.Now) 
    { 
     Console.WriteLine("{0} {1}",message, datetime); 
    }; 

Console.WriteLine(sum(40)); 
print("Hello"); 
+0

Spiegare per favore Cosa si vuole ottenere. –

+1

@Sudhakar, l'OP vuole definire un 'Action' o' Func' con parametri opzionali (cioè i parametri con valori predefiniti). –

+0

possibile duplicato di [Parametro azione in cui T3 può essere facoltativo] (http://stackoverflow.com/questions/7690482/parameter-actiont1-t2-t3-in-which-t3-can-be-optional) –

risposta

7

Come indicato here -

I parametri facoltativi sono un attributo di un metodo o un parametro delegato . Quando si chiama una firma (metodo o delegato) che ha un parametro facoltativo noto in fase di compilazione, il compilatore inserirà il valore di parametro opzionale nel callsite.

Il runtime non è a conoscenza dei parametri facoltativi, quindi non è possibile creare un delegato che inserisce un parametro facoltativo quando viene chiamato.

Quindi, per utilizzare che è necessario estrarre l'implementazione concreta (delegato personalizzato) che è noto in fase di compilazione e sostituirà i parametri sul sito di chiamata con parametri opzionali e parametri denominati possono essere utilizzati pure.

Declare personalizzato delegato -

public delegate int FuncDelegate(int x, int y = 20); 

Ora è possibile utilizzarlo in modalità corpo -

FuncDelegate sum = delegate(int x, int y) { return x + y; }; 
int result = sum (x : 20, y: 40); 
result = sum(20); 

Inoltre, solo compile time constant can be used in default parameters list. Ma non è possibile utilizzarlo anche per specificare il valore facoltativo del parametro.

Così, per parte di azione questo funzionerà -

public delegate void ActionDelegate(string message, 
            DateTime dateTime = default(DateTime)); 

Usa delegato ora qui -

ActionDelegate print = 
       delegate(string message, DateTime dateTime) 
       { Console.WriteLine(dateTime.ToString()); }; 
print(dateTime: DateTime.Now, message: "SomeThing"); 
+0

Sto parlando dei delegati di Action e Func. Non ha funzionato. –

+0

Sì, quello che ho detto che il parametro opzionale può essere usato solo su metodi e delegati in fase di compilazione. Func e Actions sono più di runtime e non in fase di compilazione. –

2

Hai una risposta per la parte parametro opzionale. Per quanto riguarda il parametro denominato, è del tutto possibile fornire nomi per gli argomenti, ma solo che x e non sono i nomi dei parametri per i delegati generici Action/Func. Se si dispone di un delegato ha dichiarato come questo:

delegate void D(int p); 

//now 
D x = a => { }; 

x(a: 1); //is illegal, since 'a' is not the name of the parameter but 'p'; so 
x(p: 1) //is legal 

a davvero impossibile essere che il nome del parametro, perché a è solo una parte della firma del metodo corrente il delegato riferimenti a (cioè il metodo anonimo). Non fa realmente parte della firma del delegato originale. Pensa a questo scenario:

D x = a => { }; 

//and somewhere else 
x = b => { }; 

//and yet again 
x = SomeMethod; 

// now should it be x(a: 1) or x(b: 1) or x(parameterNameOfMethodSomeMethod: 1)? 

Solo p ha senso lì.

Nel caso di Action/Func sono dichiarate come:

public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2); 
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2); 

Così si vede il parametro denominazione giusta? Quindi in questo caso:

Func<int, int, int> sum = delegate(int x, int y) { return x + y; }; 
Action<string, DateTime> print = 
    delegate(string message, DateTime datetime) { Console.WriteLine("{0} {1}", message, datetime); }; 

//and you should be calling them like: 

Console.WriteLine(sum(arg1: 20, arg2: 40)); 
print(arg2: DateTime.Now, arg1: "Hello"); //note the order change here 

Ovviamente non ha senso in questo scenario poiché non si utilizza alcun parametro facoltativo.

Problemi correlati