C# 对'Action'委托和lambda表达式的混淆
我不明白为什么C# 对'Action'委托和lambda表达式的混淆,c#,delegates,lambda,C#,Delegates,Lambda,我不明白为什么TestDelegateStatement3可以工作,但是testdelegatestatement 1失败了。在这两种情况下,Action都提供了一个采用零参数的方法。他们可以调用一个采用单个参数(aString)的方法,但这应该是无关的。它们不接受参数。这是lamda表达式不可能实现的,还是我做错了什么?在C#2.0中,操作委托是一个不接受参数的无效委托。 在以后的版本中,有一个通用的操作委托,其中T指定参数类型 这应该起作用: private void StringActio
TestDelegateStatement3
可以工作,但是testdelegatestatement 1
失败了。在这两种情况下,Action
都提供了一个采用零参数的方法。他们可以调用一个采用单个参数(aString
)的方法,但这应该是无关的。它们不接受参数。这是lamda表达式不可能实现的,还是我做错了什么?在C#2.0中,操作
委托是一个不接受参数的无效
委托。
在以后的版本中,有一个通用的操作
委托,其中T指定参数类型
这应该起作用:
private void StringAction(string aString) // method to be called
{
return;
}
private void TestDelegateStatement1() // doesn't work
{
var stringAction = new System.Action(StringAction("a string"));
// Error: "Method expected"
}
private void TestDelegateStatement2() // doesn't work
{
var stringAction = new System.Action(param => StringAction("a string"));
// Error: "System.Argument doesn't take 1 arguments"
stringAction();
}
private void TestDelegateStatement3() // this is ok
{
var stringAction = new System.Action(StringActionCaller);
stringAction();
}
private void StringActionCaller()
{
StringAction("a string");
}
我不是这方面的专家,但你试过吗
stringAction("Hello world");
正如你所说,行动不需要任何参数。 如果您这样做:
public void TestDelegateStatement4
{
var stringAction = () => StringAction("a string");
}
var stringAction = new System.Action(StringAction("a string"));
实际上,您在这里执行该方法,因此它不是一个方法参数
如果您这样做:
public void TestDelegateStatement4
{
var stringAction = () => StringAction("a string");
}
var stringAction = new System.Action(StringAction("a string"));
您告诉它您的方法采用了一个名为param
的参数,而该操作不采用该参数
因此,正确的方法是:
var stringAction = new System.Action(param => StringAction("a string"));
或更紧凑:
var stringAction = new System.Action( () => StringAction("a string"));
空括号用于表示lambda不接受任何参数。
操作
委托被定义为委托给方法,它没有参数并返回void。在示例1中,您犯了两个错误:1.您试图给出一个方法,该方法采用参数
2.您正在调用该方法,但没有将其作为参数提供(它应该是new Action(methodName)),尽管由于1的原因,它无法工作 在示例2中,您又犯了同样的错误,您的lambda接受了一个参数,您应该这样写:
newaction(()=>StringAction(“字符串”))代码>
如果要创建一个将接受一个参数的委托,应该这样做:
newaction(myStringParam=>StringAction(myStringParam))代码>
因此,在您的情况下,完整的代码如下所示:
Action stringAction = () => StringAction("a string");
private void StringAction(string aString)//要调用的方法
{
返回;
}
private void TestDelegateStatement1()//现在可以工作了
{
var stringAction=新操作(stringAction);
//您现在可以称之为:
stringAction(“我的字符串”);
}
private void TestDelegateStatement2()//现在可以工作了
{
var stringAction=()=>stringAction(“字符串”);
//或相同,带有参数:
变量stringActionParam=(param)=>StringAction(param);
//您现在可以同时调用这两个:
stringAction();
stringActionParam(“我的字符串”);
}
private void TestDelegateStatement3()//这没问题
{
var stringAction=new System.Action(StringActionCaller);
stringAction();
}
私有void StringActionCaller()
{
StringAction(“字符串”);
}
@Botz:对您的“更紧凑”语句的轻微更正:System.Action stringAction=()=>stringAction(“字符串”)代码>(编译器没有足够的信息知道var
是一个System.Action
)。
private void StringAction(string aString) // method to be called
{
return;
}
private void TestDelegateStatement1() // now it works
{
var stringAction = new Action<string>(StringAction);
//You can call it now:
stringAction("my string");
}
private void TestDelegateStatement2() // now it works
{
var stringAction = () => StringAction("a string");
//Or the same, with a param:
var stringActionParam = (param) => StringAction(param);
//You can now call both:
stringAction();
stringActionParam("my string");
}
private void TestDelegateStatement3() // this is ok
{
var stringAction = new System.Action(StringActionCaller);
stringAction();
}
private void StringActionCaller()
{
StringAction("a string");
}