c# - 无法确定条件表达式的类型?

标签 c# .net compiler-construction

<分区>

我刚遇到这个(编写代码来演示“问题”):

public ICollection<string> CreateCollection(int x)
{
    ICollection<string> collection = x == 0 
                                   ? new List<string>() 
                                   : new LinkedList<string>();
    return collection;
}

编译器提示:

Fehler CS0173: Der Typ des bedingten Ausdrucks kann nicht bestimmt werden, weil keine implizite Konvertierung zwischen "System.Collections.Generic.List" und "System.Collections.Generic.LinkedList" erfolgt.

大致翻译为:

The type of the conditional operator can not be determined, because there is no implicit conversion between List and LinkedList.

我明白为什么编译器会提示,但是嘿,来吧。它试图装傻。我可以看到这两个表达式不是同一类型,但有一个共同的祖先,作为奖励,左侧的类型也是一个共同的祖先。我相信编译器也能看到它。如果左侧被声明为 var,我可以理解这个错误。

我在这里错过了什么?

编辑:

我接受 James Gaunt 的解释。也许只是为了说清楚。我可以很好地阅读编译器规范。我想明白为什么。为什么有人决定以这种方式编写规范。这种设计背后一定有原因。根据詹姆斯的设计原则是“没有惊喜”。 CodeInChaos 还解释了如果编译器尝试从共同祖先推断出类型,您可能会遇到什么意外。

最佳答案

表达式 (a ? b : c) 必须解析为一个类型。类型将是 b 或 c 的类型。如果它们不同(并且没有从一个到另一个的隐式转换),编译器在编译时不知道这是哪种类型。

你可能会说它应该推断出有共同的根类型,但总有一个共同的根类型(例如 Object)。

通常,C# 编译器不会尝试猜测您的意思。如果您想使用公共(public)根类型,则将 b 和 c 强制转换为该类型。

这种逻辑贯穿于 C# 的设计之中,它偶尔会有点烦人,但更多时候它会阻止你犯错。

关于c# - 无法确定条件表达式的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4424231/

相关文章:

c# - 形状比应有的要大

c - 从多个源文件构建内核模块

c++ - 我可以获得编译器应用的优化日志吗?

c# - Windows Phone 8.0 证书固定

c# - 如何将 POCO 对象列表绑定(bind)到 Windows 窗体 DataGrid

c# - 如何创建悬停的 C# Winforms 控件

compiler-construction - Scala:比较新鲜的对象

c# - 在这种情况下抛出什么类型的异常?

c# - 我应该重用 FileStream/BinaryWriter 对象吗?

c# - 如何使 TaskCompletionSource.Task 使用特定的 TaskScheduler 完成