Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#mono出现奇怪的编译器错误_C#_Compiler Errors_Mono - Fatal编程技术网

C#mono出现奇怪的编译器错误

C#mono出现奇怪的编译器错误,c#,compiler-errors,mono,C#,Compiler Errors,Mono,我有以下代码: int? sum=Enumerable.Range(0, 1000).Sum((i) => { if (((i % 3) == 0) && ((i % 5) == 0)) return i; return null; }); 此代码未编译,它生成以下错误: 错误CS0266:无法将类型“decimal”隐式转换为“int”。存在显式转换(是否缺少

我有以下代码:

int? sum=Enumerable.Range(0, 1000).Sum((i) =>
        {
            if (((i % 3) == 0) && ((i % 5) == 0))
                return i;
            return null;
        });
此代码未编译,它生成以下错误:

错误CS0266:无法将类型“decimal”隐式转换为“int”。存在显式转换(是否缺少强制转换?)

我将代码更改为:

int? sum=Enumerable.Range(0, 1000).Sum<int>((int i) =>
        {
            if (((i % 3) == 0) && ((i % 5) == 0))
                return i;
            return null;
        });
int?总和=可枚举范围(0,1000)。总和((整数i)=>
{
如果((i%3)==0)和((i%5)==0))
返回i;
返回null;
});
但编译器错误仍然存在

我不明白,
Enumerable.Range
返回一组整数,很明显我想要返回int的
Sum
,否则,
i
应该是
decimal
,正如我所说,在
i
之前插入
int
并不重要

当我将
sum
a
decimal?
变量设置为它编译的变量时

我想这可能是一个单声道错误,我在错误列表中没有看到类似的东西

那么,我是遗漏了什么,还是应该提交一个bug


我的mono版本是4.4.1,我的操作系统是Arch linux x64。

肯定是个bug,因为VisualStudio附带的编译器不会出现这种情况

mono的一个解决方法似乎是返回
default(int?
而不是null

int? sum=Enumerable.Range(0, 1000).Sum((i) =>
    {
        if (((i % 3) == 0) && ((i % 5) == 0))
            return i;
        return default(int?);
    });

下面是一个简化的测试程序,它演示了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);
  }
}
使用系统;
使用静态系统控制台;
静态类程序{
静态void Test1(Func f){WriteLine(“Test1(Func)”;}
静态void Test1(Func f){WriteLine(“Test1(Func)”;}
静态void Test2(Func f){WriteLine(“Test2(Func)”;}
静态void Test2(Func f){WriteLine(“Test2(Func)”;}
静态void Main(){
Test1(()=>null);
Test2(()=>null);
}
}
当使用Mono(4.4)编译时,它会打印:

Test1(Func<decimal?>)
Test2(Func<int?>)
Test1(Func<int?>)
Test2(Func<int?>)
Test1(Func)
测试2(Func)
使用Roslyn编译时,此文件将打印:

Test1(Func<decimal?>)
Test2(Func<int?>)
Test1(Func<int?>)
Test2(Func<int?>)
Test1(Func)
测试2(Func)
在讨论C#5.0语言规范时,最终应该选择哪种重载可以归结为7.5.3.3更好地从表达式转换,但它没有解决这个问题。它给出了一些特定的场景,其中一个重载优于另一个重载,但要在这里工作,它需要根据它所称的推断返回类型进行操作。但是,
null
没有类型。没有推断的返回类型。这使得我们在语言规范中没有描述要使用哪个重载的内容

5.0语言规范称该调用不明确。编译器应生成一个错误。


不幸的是,语言规范没有描述微软的编译器。这迫使Mono实施丑陋的黑客攻击,试图模仿微软的行为,因为拒绝编译使用微软编译器编译的代码是一种让人们不把Mono当回事的简单方法,正如你在回答这个问题时看到的那样。这些丑陋的黑客不是完美的,除非规范正确描述了他们设计的语言,否则可能永远也不会完美

一个非官方的C#6.0语言规范已在上公布。它描述了重载解析规则的一些调整(查看7.5.3.3更好的表达式转换和7.5.3.5更好的转换目标):

  • int?
    是比
    decimal?
    更好的转换目标,因为存在从
    int?
    decimal?
    的隐式转换,但不是相反
  • 因此,
    Func
    是比
    Func
    更好的转换目标
  • 因此,从
    ()=>null
    Func
    的转换比
    Func
6.0语言规范可能会说代码是有效的,Roslyn是对的。但该语言规范尚未最终确定。

由于C#6.0语言规范尚未最终确定,Mono很难准确实现它,而且似乎还没有完成


不管你是将其视为解决Mono bug或缺少的功能,还是将其视为修复代码以使其更兼容C#5.0,结果都是一样的:使用
default(int?
,而不是Steve建议的
null
,都会使其工作。在C#5.0中,它的工作方式是给匿名函数一个推断的返回类型
int?
,以有利于所需重载的方式解决歧义。

从:(int i)到:(int)i@jdweng我不明白你的意思。然后,向mono报告错误:在dotnetfiddle中,你的代码没有错误。@x。。。谢谢,我刚刚做了“肯定是个bug,因为VisualStudio附带的编译器不会出现这种情况。”——C#应该由语言规范定义。这种语言规范没有明确说明某些事情。如果是这样,那么代码中的错误就是依赖于未指定的行为。虽然我怀疑语言规范确实定义了行为,并以与对待它相同的方式对其进行了定义,但答案应该真正显示语言规范(或MS文档)在何处定义了哪些
Sum
重载应被称为“语言规范未描述Microsoft的编译器”因此,如果我使用visual studio 2013(或者更具体地说是旧版编译器,它不是Roslyn),我会得到相同的编译器错误@niceman我相当肯定旧版编译器和C#5.0规范不匹配,甚至在规范允许之前,它已经按照您期望的方式工作了。如果可以,我会做一个快速检查。@niceman使用.NET Framework提供的csc.exe,它不实现C#6.0,并抱怨我的
使用static
,更改后,我的答案中的代码被标记为不明确。但是,如果我将
()=>null
更改为
()=>{return 0;return null;}
类似于您所拥有的,那么