C# 操作与Func相同<;TResult>;?
我遇到了一个我需要一些知识的情况 代码如下:C# 操作与Func相同<;TResult>;?,c#,.net,lambda,delegates,C#,.net,Lambda,Delegates,我遇到了一个我需要一些知识的情况 代码如下: // A function to match the delegate public static int DoSomething() { Console.WriteLine("i am called"); return 1; } // Usage Action action = () => DoSomething(); Func<int> func = () => DoSomething(); action()
// A function to match the delegate
public static int DoSomething()
{
Console.WriteLine("i am called");
return 1;
}
// Usage
Action action = () => DoSomething();
Func<int> func = () => DoSomething();
action();
func();
//与委托匹配的函数
公共静态int DoSomething()
{
Console.WriteLine(“我被召唤”);
返回1;
}
//用法
动作动作=()=>DoSomething();
Func Func=()=>DoSomething();
动作();
func();
我对操作的理解是,它应该匹配不接受任何参数且不返回任何内容的委托
对于Func
,它应该匹配不接受任何参数并返回int
的委托
DoSomething
方法返回一个整数,因此我的问题是:()=>DoSomething()
是一个返回int
的委托Func
按预期工作,但Action
不工作。为什么?我在这里不明白什么
代码编译和运行正常,两个输出都我被调用
。我想知道的是为什么Action-Action=()=>DoSomething()
不是编译时错误吗?C编译器足够聪明,能够根据上下文判断出()=>DoSomething()
的含义不同。当您使用它分配一个Action
变量时,它会生成一个Action
(而不是Func
),忽略DoSomething()
Action Action=()=>DoSomething()的返回结果
相当于
Action Action=()=>{DoSomething();}代码>
Func-Func=()=>DoSomething()
相当于
Func=()=>{return DoSomething();}代码>
我想知道的是为什么Action-Action=()=>DoSomething()代码>不是编译时错误吗
它之所以编译,是因为有一个lambda表达式调用该方法,但忽略了结果。无法使用方法组转换,例如
// Compile-time failure
// error CS0407: 'int Test.DoSomething()' has the wrong return type
Action action = DoSomething;
(对于Func
可以使用相同的方法进行组转换。)
但实际上,你做的事情更像这样:
Action action = DoSomethingAndIgnoreResult;
...
private static void DoSomethingAndIgnoreResult()
{
DoSomething(); // Hey, I'm ignoring the result. That's fine...
}
你的理解都是正确的。可能会引起混淆的是您的具体用法。Func和Action都很好。两个电话都很好。我认为可以说明你的问题的情况是:
var x=动作(5);//不好
变量y=func(5);//好的
您的示例代码只是忽略了返回值,这就是为什么它们看起来是一样的。无异于
voidfoo1(intx){return;}
void Foo2(int x){return 1;}
Foo1(5);
Foo2(5)代码>
DoSomething
方法返回一个整数,因此我的问题是:(x)=>DoSomething(x)
是一个接受对象并返回int
的委托Func
按预期工作,但Action
不工作。为什么?我在这里不明白什么
您理解中的缺陷就在这里:(x)=>DoSomething(x)
没有类型。这不是什么。编译器需要上下文来确定它的类型。lambda本身并不是什么特别的东西,这就是为什么不能将var
与lambda表达式一起使用的原因:编译器不知道lambda应该是什么类型,因此无法推断该类型
例如,(x)=>DoSomething(x)
也可以是表达式树:
Expression<Func<object, int>> e = (x) => DoSomething(x)
表达式e=(x)=>DoSomething(x)
因此,您正在告诉编译器如何根据分配给它的类型解释lambda。>>但是操作没有-它到底是如何失败的?代码行Action Action=(x)=>DoSomething(x)这不应该是编译时错误吗,因为操作
需要匹配不返回值的委托?@singsuyash C#编译器足够聪明,能够发现(x)=>DoSomething(x)
根据上下文意味着不同的事情。当您使用它分配一个Action
变量时,它会生成一个Action
,而不是Func
,并忽略DoSomething(x)
的返回结果。您可以调用DoSomething
方法并“忽略”返回值(例如DoSomething(x)
),并且可以使用返回值(例如,var retVal=DoSomething(x)
)-两者都可以工作和编译。您的问题是什么?您的代码非常好,可以编译并运行。值得注意的是,方法组转换的错误类似于预期的带有“void DoSomething(object)”的方法'签名
@DaveZych:Done,以及我收到的实际错误消息。感谢@JonSkeet提供更新的答案:)是的,我以后会小心不要这样更改它。