在三元/条件运算符中转换时出现奇怪的编译器错误

时间:2010-08-23 18:32:12

标签: c# casting operators

我在使用此代码时遇到意外的编译器错误:

bool b = true; //or false
StringBuilder builder = ...; // a string builder filled with content
IVersePart vp = b ? (DualLanguageVersePart)builder : (VersePart)builder;

DualLanguageVersePart和VersePart都实现了IVersePart接口。 DualLanguageVersePart和VersePart都有一个显式的转换运算符形式StringBuilder。

由于两个类都实现了vp类型的接口,我希望这可以完美地工作,或者至少可以正确编译。相反,编译器报告在两种类型之间不能进行隐式转换。

为什么这不起作用?

6 个答案:

答案 0 :(得分:2)

两个部分必须具有相同的类型,所以试试这个:

IVersePart vp = b ? 
  (IVersePart)(DualLanguageVersePart)builder :
  (IVersePart)(VersePart)builder;

C#编译器比C ++编译器更麻烦:)

答案 1 :(得分:2)

这是一个糟糕的设计。不应该像这样使用演员操作符。

最好有一个ctor来处理这个问题(因为你正在尝试构建一个新对象)

IVersePart vp = new DualLanguageVersePart(builder);

或者,您可以使用工厂:

IVersePart vp = VersePart.DualOrSingluar(builder, b);

答案 2 :(得分:1)

之前我遇到过这个问题,三元运算符要求两种类型的true结果或者false结果都是相同的类型,或者将它们转换为相同的类型。

答案 3 :(得分:0)

三元运算符需要能够返回一种类型,因为它只是一个语句。因此,当操作符的两个部分返回不同的类型时,编译器将尝试通过静默地将一个转换为另一个来允许它。您没有从DualLanguageVersePart到VersePart的转换,反之亦然。

一个简单的解决方法是将第二个演员添加到IVersePart

IVersePart vp = b ? (IVersePart)(DualLanguageVersePart)builder : (IVersePart)(VersePart)builder;

答案 4 :(得分:0)

三元操作需要true和false才能返回相同的类型。这是解决这个问题的一种方法,虽然有点马虎......

IVersePart vp = b 
    ? (IVersePart)((DualLanguageVersePart)builder) 
    : (IVersePart)((VersePart)builder); 

答案 5 :(得分:-1)

任何运算符的结果类型(operator implicit除外)由操作数而不是上下文决定。

与这里所分配的大部分智慧相反,两种论点都不一定是同一类型。如果一个类型是从另一个派生的,则三元运算符结果将是基本类型。但在您的示例中,有多种常见的基类型:至少ObjectIVersePart,而C#语言不会让编译器试图找出哪个更好。