为什么不可能执行以下操作:
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 :(得分: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
因此也不能用于为参数指定可选值。
因此,对于Action部分,这将起作用 -
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");
答案 1 :(得分:2)
您有可选参数部分的答案。关于命名参数,它完全可以为参数提供名称,但x
和y
不是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
当然,在这种情况下它没有任何意义,因为你没有使用任何可选参数。
答案 2 :(得分:0)
C#7现在允许'local functions'。因此,您可以编写“正常”方法来代替创建#include<iostream>
using namespace std;
int main()
{
string user_input;
double price;
do
{
cin >> price;
int multiple = price * 100;
if (user_input == "q")
{
break;
}
else if (multiple % 5 == 0)
{
cout << "This is a multiple of 0.05" << endl;
return 1;
}
else
{
cout << "No multiple" << endl;
}
} while (1 || user_input != "q");
system("pause");
}
或Action<T>
。这意味着适用默认参数的一般规则。
因此,您可以在不使用委托语法的情况下将某些逻辑范围限定在函数内部。
它也像闭包一样工作,因此您可以通过'parent'方法访问局部变量。
我在下面的Microsoft示例中添加了一个毫无意义的Func<T>
可选参数。
throwAnException