2013-11-03 64 views
7

爲什麼這是不可能的可選參數和命名參數做到以下幾點:只有命名的參數使用的行動和Func鍵代表

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"); 

情況:

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"); 

的情況下,只有可選參數:

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

請說明你想達到什麼目的。 –

+1

@Sudhakar,OP想要用可選參數(即具有默認值的參數)定義一個「Action」或「Func」。 –

+0

可能重複的[參數動作其中T3可以是可選的](http://stackoverflow.com/questions/7690482/parameter-actiont1-t2-t3-in-which-t3-can-be-optional) –

回答

7

如上所述here -

可選參數是方法或委託參數 的參數。當您在編譯時調用具有 已知可選參數的簽名(方法或委託)時,編譯器會在調用點處插入 可選參數值。

運行時不知道可選參數,因此您無法創建一個 委託,該委託會在調用它時插入一個可選參數。

因此,要使用該功能,您必須提取在編譯時已知的具體實現(自定義委託),並使用可選參數和命名參數替換呼叫站點上的參數。

聲明自定義的委託 -

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

現在你可以在方法體中使用它 -

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

此外,只有compile time constant can be used in default parameters list。 但是DateTime.Now is not a compile time constant因此不能用於指定參數的可選值。

所以行動的一部分,這將工作 -

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

使用現在這裏的委託 -

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

我正在談論Action和Func的代表,那不適用。 –

+0

是的,我所說的可選參數只能在編譯時在方法和委託上使用。 Func和Actions更多的是運行時,而不是在編譯時。 –

2

你必須爲可選參數部分答案。關於命名參數,它完全可能爲參數提供名稱,但xy不是Action/Func通用代表的參數名稱。如果你有申報這樣的委託:

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真的不能是參數的名稱,因爲a只是當前方法的簽名您的代理引用(即匿名方法)的一部分。這不是真正的代表簽名的一部分。想想這種情況:

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)? 

只有p在那裏是有道理的。

Action/Func的情況下,他們宣稱這樣的:

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); 

所以你看參數冠名權?所以在這種情況下:

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 

當然,在這種情況下它沒有意義,因爲您沒有使用任何可選參數。