Mar*_*lon 136 c# lambda delegates implicit-typing .net-3.5
我有以下代码:
Func<string, bool> comparer = delegate(string value) {
return value != "0";
};
Run Code Online (Sandbox Code Playgroud)
但是,以下内容无法编译:
var comparer = delegate(string value) {
return value != "0";
};
Run Code Online (Sandbox Code Playgroud)
为什么编译器无法弄清楚它是Func<string, bool>
什么?它需要一个字符串参数,并返回一个布尔值.相反,它给了我错误:
无法将匿名方法分配给隐式类型的局部变量.
我有一个猜测,那就是如果编译var版本,如果我有以下内容,它将缺乏一致性:
var comparer = delegate(string arg1, string arg2, string arg3, string arg4, string arg5) {
return false;
};
Run Code Online (Sandbox Code Playgroud)
上面没有意义,因为Func <>只允许最多4个参数(在.NET 3.5中,这就是我正在使用的).也许有人可以澄清这个问题.谢谢.
Eri*_*ert 151
其他人已经指出,你可能有无数种可能的委托类型; 什么特别之处Func
,它不愧为默认的替代Predicate
或Action
或任何其他可能性?而且,对于lambdas,为什么明显的意图是选择委托形式,而不是表达树形式?
但我们可以说这Func
是特殊的,并且lambda或匿名方法的推断类型是Func of something.我们仍然有各种各样的问题.您希望在以下情况下推断出哪些类型?
var x1 = (ref int y)=>123;
Run Code Online (Sandbox Code Playgroud)
没有任何Func<T>
类型需要参考任何东西.
var x2 = y=>123;
Run Code Online (Sandbox Code Playgroud)
我们不知道形式参数的类型,尽管我们知道返回.(或者我们呢?返回int?long?short?byte?)
var x3 = (int y)=>null;
Run Code Online (Sandbox Code Playgroud)
我们不知道返回类型,但它不能无效.返回类型可以是任何引用类型或任何可以为null的值类型.
var x4 = (int y)=>{ throw new Exception(); }
Run Code Online (Sandbox Code Playgroud)
同样,我们不知道返回类型,这次它可能是无效的.
var x5 = (int y)=> q += y;
Run Code Online (Sandbox Code Playgroud)
这是否是一个返回void的语句lambda或返回分配给q的值的东西?两者都是合法的; 我们应该选择哪个?
现在,您可能会说,嗯,只是不支持任何这些功能.只需支持可以解决类型的"正常"情况.这没有用.这怎么能让我的生活更轻松?如果该功能有时有效并且有时会失败,那么我仍然必须编写代码来检测所有这些失败情况,并为每个失败情况提供有意义的错误消息.我们仍然必须指定所有行为,记录它,为它编写测试,等等.这是一个非常昂贵的功能,可以为用户节省六个键击.我们有更好的方法来增加语言的价值,而不是花费大量时间为一部分时间不起作用的功能编写测试用例,并且在它工作的情况下几乎没有提供任何好处.
它实际上有用的情况是:
var xAnon = (int y)=>new { Y = y };
Run Code Online (Sandbox Code Playgroud)
因为那件事没有"可说的"类型.但是我们一直都有这个问题,我们只是使用方法类型推断来推断出类型:
Func<A, R> WorkItOut<A, R>(Func<A, R> f) { return f; }
...
var xAnon = WorkItOut((int y)=>new { Y = y });
Run Code Online (Sandbox Code Playgroud)
现在方法类型推断可以解决func类型的问题.
ito*_*son 29
只有Eric Lippert肯定知道,但我认为这是因为委托类型的签名并不能唯一地确定类型.
考虑你的例子:
var comparer = delegate(string value) { return value != "0"; };
Run Code Online (Sandbox Code Playgroud)
以下是var
应该是什么的两种可能的推论:
Predicate<string> comparer = delegate(string value) { return value != "0"; }; // okay
Func<string, bool> comparer = delegate(string value) { return value != "0"; }; // also okay
Run Code Online (Sandbox Code Playgroud)
编译器应推断出哪一个?选择其中一个是没有充分理由的.虽然a Predicate<T>
在功能上等同于a Func<T, bool>
,但它们仍然是.NET类型系统级别的不同类型.因此,编译器无法明确地解析委托类型,并且必须使类型推断失败.
不同的代表被认为是不同的类型.例如,Action
不同于MethodInvoker
,并且Action
不能将实例分配给类型的变量MethodInvoker
.
所以,给定一个匿名委托(或lambda)() => {}
,是一个Action
还是一个MethodInvoker
?编译器无法分辨.
类似地,如果我声明一个委托类型接受一个string
参数并返回一个bool
,编译器如何知道你真的想要一个Func<string, bool>
而不是我的委托类型?它无法推断委托类型.
归档时间: |
|
查看次数: |
36011 次 |
最近记录: |