我在使用此代码时遇到意外的编译器错误:
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
类型的接口,我希望这可以完美地工作,或者至少可以正确编译。相反,编译器报告在两种类型之间不能进行隐式转换。
为什么这不起作用?
答案 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
除外)由操作数而不是上下文决定。
与这里所分配的大部分智慧相反,两种论点都不一定是同一类型。如果一个类型是从另一个派生的,则三元运算符结果将是基本类型。但在您的示例中,有多种常见的基类型:至少Object
和IVersePart
,而C#语言不会让编译器试图找出哪个更好。