我有这个代码:
int? sum=Enumerable.Range(0, 1000).Sum((i) =>
{
if (((i % 3) == 0) && ((i % 5) == 0))
return i;
return null;
});
这段代码没有编译,它产生了这个错误:
错误CS0266:无法隐式转换类型“十进制?” 到“ int?”。存在显式转换(您是否缺少演员表?)
我将代码更改为此:
int? sum=Enumerable.Range(0, 1000).Sum<int>((int i) =>
{
if (((i % 3) == 0) && ((i % 5) == 0))
return i;
return null;
});
但是编译器错误仍然存在。
我不明白,Enumerable.Range
返回整数的集合,很明显我想要Sum
返回int的整数吗?,否则i
应该是decimal
,正如我说的,是否插入int
之前i
没有关系。
当我创建sum
一个decimal?
变量时,它将进行编译。
我认为这可能是一个单声道错误,在此错误列表中没有看到类似的内容。
那么,我是否缺少某些东西还是应该提交错误?
我的单声道版本是4.4.1,我的操作系统是Arch linux x64。
这是一个精简的测试程序,该程序演示了BCL之外的问题:
using System;
using static System.Console;
static class Program {
static void Test1(Func<int?> f) { WriteLine("Test1(Func<int?>)"); }
static void Test1(Func<decimal?> f) { WriteLine("Test1(Func<decimal?>)"); }
static void Test2(Func<decimal?> f) { WriteLine("Test2(Func<decimal?>)"); }
static void Test2(Func<int?> f) { WriteLine("Test2(Func<int?>)"); }
static void Main() {
Test1(() => null);
Test2(() => null);
}
}
使用Mono(4.4)进行编译时,将输出:
Test1(Func<decimal?>)
Test2(Func<int?>)
当使用Roslyn编译时,将输出:
Test1(Func<int?>)
Test2(Func<int?>)
最终,当通过C#5.0语言规范时,应该选择哪种重载可以归结为7.5.3.3从expression更好的转换,但是不能解决这种情况。它提供了一些特定的方案,其中一种重载要比另一种重载更好,但要使其在这里起作用,就需要对其所谓的推断返回类型进行操作。但是,null
没有类型。没有推断的返回类型。这使我们在描述要使用的重载的语言规范中一无所获。
5.0语言规范说该调用是模棱两可的。编译器应产生一个错误。
不幸的是,语言规范没有描述Microsoft的编译器。这迫使Mono实现了模仿Microsoft行为的丑陋骇客,因为拒绝编译可以与Microsoft编译器一起编译的代码是一种容易使人们不认真对待Mono的方法,就像您在回答此问题时所看到的那样。 。除非规范正确地描述了他们设计的语言,否则这些丑陋的hacks并不是完美的,而且可能永远也不会完美。
非正式的C#6.0语言规范已在https://github.com/ljw1004/csharpspec/blob/gh-pages/README.md中公开。它描述了对重载解析规则的一些调整(寻找7.5.3.3从表达式更好的转换和7.5.3.5更好的转换目标):
int?
与相比decimal?
,是更好的转换目标,因为存在从int?
到的隐式转换decimal?
,反之亦然。Func<int?>
是比更好的转化目标Func<decimal?>
。() => null
到的转换Func<int?>
比更好Func<decimal?>
。6.0语言规范可能会说代码是有效的,而Roslyn是正确的。但是该语言规范尚未最终确定。
由于C#6.0语言规范尚未最终确定,因此Mono难以准确实现它,而且似乎尚未完成。
无论是将其视为Mono错误或缺少功能的解决方法,还是将其视为与C#5.0更加兼容的代码修复,其结果都是相同的:如史蒂夫(Steve)所建议,使用default(int?)
而不是()null
也会使这行得通。在C#5.0中,其工作方式是通过为匿名函数提供推断的返回类型int?
,从而解决了期望的重载方面的歧义。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句