不能使用三元运算符来分配Linq表达式

我只输入以下代码:

Expression<Func> expression = fileTypeGroupID.HasValue ? n => n.Document.MimeType.FileTypeGroupID == fileTypeGroupID.Value : n => true; 

Visual Studio说它无法推断出n的类型。

代码对我来说似乎很好 – 它只是使用三元运算符将两个Expression文字中的一个指定给Expression变量。

Visual Studio是不是很聪明,无法推断出三元运算符中的n类型,还是我犯了某种错误?

几乎每天都会以某种forms询问这个问题。

条件运算符类型分析从 ,而不是从 。 条件运算符不知道其结果被分配的类型 ,然后强制后果和这些类型的替代 。 它恰恰相反; 它计算出结果和替代的类型,采用这两种类型的更一般,然后validation可以分配一般类型。

结果和替代方案不包含关于lambda的类型应该是什么的信息,因此不能推断出条件的类型。 因此无法validation分配是否正确。

它正在考虑为什么语言是这样设计的。 假设你有重载:

  void M(Func f) {} void M(Func f) {} 

和一个电话

 M( b ? n=>n.Foo() : n => n.Bar() ); 

描述过载分辨率如何确定在从外到内推断类型的世界中选择M的哪个过载。

现在考虑一下:

 M( b1 ? (b2 ? n=>n.Foo() : n => n.Bar() ) : (b3 ? n=>n.Blah() : n=>n.Abc()) ); 

变得更难不是吗? 现在想象一下,Foo,Bar,Blah和Abc本身就是采用funcs的方法,并且还有包含lambdas的条件运算符的参数。

我们不希望类型推断过程如此复杂而没有相应的巨大好处,并且条件运算符没有这么大的好处。

在您的情况下,您应该做的是投射特定类型的一个或两个结果和替代。

这并没有回答你为什么编译器无法推断出类型的问题,但一个简单的解决方法就是以这种方式编写表达式:

 Expression> expression = n => !fileTypeGroupID.HasValue || n.Document.MimeType.FileTypeGroupID == fileTypeGroupID.Value; 
 fileTypeGroupID.HasValue ? (ContentItem n) => n.Document.MimeType.FileTypeGroupID == fileTypeGroupID.Value : (ContentItem n) => true; 

注意条件运算符是正确的名称? : ? :这是三元运算符的一个例子(并且是许多编程语言中唯一的三元运算符)。