2

可能重复:
在 C# 中使用条件运算符键入结果

基本上我有一些这样的代码:

IEnumerable<Effect> effects = ( ( activeOnly ) ? this.ActiveEffects : this.AllEffects ).Select ( e => e );

在哪里:

this.ActiveEffects is:
class ActiveEffectList : IEnumerable<Effect>

this.AllEffects is:
class EffectList : IEnumerable<Effect>

这就是为什么我希望上面的语句可以工作,但是它返回了这个编译错误:

无法确定条件表达式的类型,因为 'ImageEditor.ActiveEffectList' 和 'ImageEditor.EffectList' 之间没有隐式转换

4

4 回答 4

1

您可以通过将第一个值转换为 来解决此问题IEnumerable<Effect>

var effects = activeOnly ?
              (IEnumerable<Effect>) this.ActiveEffects :
              this.AllEffects;

问题是,即使您分配给 IEnumerable,编译器也需要在强制转换发生之前评估条件表达式,并且由于条件语句需要两个路径来返回相同的类型,所以您会收到一个AllEffects无法强制转换的错误到ActiveEffects.

通过将语句中的第一个值强制转换为 IE numerable<Effect>,您将强制条件语句返回IEnumerable<Effect>而不是返回更具体的类型之一。

于 2011-02-01T20:23:29.290 回答
1

因为它在解析类型时不查看基本类型或左侧类型。

您可以通过将语句更改为:

IEnumerable<Effect> effects = ( ( activeOnly ) ? (IEnumerable<Effect>)this.ActiveEffects : this.AllEffects ).Select ( e => e );
于 2011-02-01T20:23:40.510 回答
1

因为三元表达式是一个表达式,而表达式有一个类型。编译器不会尝试找到最接近的常见赋值兼容类型(因为这样的搜索可能非常复杂并且通常没有什么价值)。在您的情况下,您有两种完全不同的类型。所有类型(通常在不安全块之外)都有一个共同的祖先 at object,但编译器不查找链;如果这两种类型至少在一个方向上没有赋值兼容性,那么你必须告诉它你想要什么。

简单的解决方案是将操作数之一转换为所需的类型。这将指示编译器将另一个操作数与该类型进行比较,它将立即视为兼容。因此,换句话说,将一个操作数转换为IEnumerable<T>.

于 2011-02-01T20:23:42.513 回答
1

您的类都继承自同一个基 (IEnumerable),但可能有不同的实现。在赋值运算符之前,三元运算符首先要返回两个值之间的共同类型,并且不能将 b 转换为 a。

根据参考:

http://msdn.microsoft.com/en-us/library/ty67wk28.aspx

first_expression 和 second_expression 的类型必须相同,或者必须存在从一种类型到另一种类型的隐式转换。

要么这样做:

IEnumerable<Effect> effects = ( ( activeOnly ) ? (IEnumerable<Effect>)this.ActiveEffects : this.AllEffects ).Select ( e => e );

或者在你的类中添加一个隐式转换运算符:

http://msdn.microsoft.com/en-us/library/z5z9kes2(VS.71).aspx

于 2011-02-01T20:37:44.957 回答