代码之家  ›  专栏  ›  技术社区  ›  astellin

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

  •  1
  • astellin  · 技术社区  · 16 年前

    我遇到意外的编译器错误,代码为:

    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 回复  |  直到 16 年前
        1
  •  1
  •   Jimmy Hoffa    16 年前

    我以前有过这个问题,三元运算符要求两种类型的真结果或假结果要么是相同的类型,要么将它们强制转换为相同的类型。

        2
  •  2
  •   Blindy    16 年前

    两个部分必须具有相同的类型,请尝试以下操作:

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

    C编译器比C++编译器更容易理解这一点:

        3
  •  2
  •   James Curran    16 年前

    这是个糟糕的设计。CAST运算符不应这样使用。

    最好有一个ctor来处理这个问题(事实上,您正在尝试构造一个新对象)

    IVersePart vp = new DualLanguageVersePart(builder);
    

    或者,您可以使用工厂:

    IVersePart vp = VersePart.DualOrSingluar(builder, b);
    
        4
  •  0
  •   Matt Greer    16 年前

    三元运算符需要能够返回一个类型,因为它只是一个语句。因此,当您让运算符的两个部分返回不同的类型时,编译器将尝试通过悄悄地将一个部分转换为另一个部分来实现这一点。您没有从duallanguageversepart到versepart的转换,反之亦然。

    一个简单的修复方法是在 IVersePart :

    IVersePart vp = b ? (IVersePart)(DualLanguageVersePart)builder : (IVersePart)(VersePart)builder;
    
        5
  •  0
  •   Jerod Houghtelling    16 年前

    三元运算要求true和false返回相同的类型。这是解决这个问题的一种方法,尽管有点草率…

    IVersePart vp = b 
        ? (IVersePart)((DualLanguageVersePart)builder) 
        : (IVersePart)((VersePart)builder); 
    
        6
  •  -1
  •   Ben Voigt    16 年前

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

    与此相反的是,这两个论点不一定是同一类型的。如果一种类型是从另一种类型派生的,则三元运算符结果将是基类型。但在您的示例中,有多个常见的基类型:至少 Object IVersePart C语言并不能让编译器试图找出哪个更好。