首页 文章

可空类型和三元运算符:为什么是`? 10:null`禁止? [重复]

提问于
浏览
225

这个问题在这里已有答案:

我刚刚遇到一个奇怪的错误:

private bool GetBoolValue()
{
    //Do some logic and return true or false
}

然后,在另一种方法中,这样的事情:

int? x = GetBoolValue() ? 10 : null;

很简单,如果方法返回true,则将10分配给Nullable int x . 否则,将null赋给 nullable int . 但是,编译器抱怨:

错误1无法确定条件表达式的类型,因为int和<null>之间没有隐式转换 .

我疯了吗?

9 回答

  • 14

    编译器首先尝试评估右 Watch 达式:

    GetBoolValue() ? 10 : null
    

    10int literal(不是 int? ), null 是,嗯, null . 这两者之间没有隐式转换因此错误消息 .

    如果将右侧表达式更改为以下之一,则会编译,因为 int?null (#1)之间以及 intint? (#2,#3)之间存在隐式转换 .

    GetBoolValue() ? (int?)10 : null    // #1
    GetBoolValue() ? 10 : (int?)null    // #2
    GetBoolValue() ? 10 : default(int?) // #3
    
  • 367

    试试这个:

    int? x = GetBoolValue() ? 10 : (int?)null;
    

    基本上发生的是条件运算符无法确定表达式的"return type" . 由于编译器隐含地决定 10int ,因此它决定该表达式的返回类型也应该是 int . 由于 int 不能 null (条件运算符的第三个操作数)它抱怨 .

    通过将 null 转换为 Nullable<int> ,我们明确地告诉编译器该表达式的返回类型应为 Nullable<int> . 您也可以轻松地将 10 转换为 int? 并具有相同的效果 .

  • 32

    试试这个:

    int? result = condition ? 10 : default(int?);

  • 4

    顺便提一下,C#编译器的Microsoft实现实际上以非常微妙和有趣(对我来说)的方式对条件运算符的类型分析进行了错误 . 我的文章是Type inference woes, part one .

  • 13

    尝试以下方法之一:

    int? x = GetBoolValue() ? (int?)10 : null;
    
    int? x = GetBoolValue() ? 10 : (int?)null;
    
  • 3

    问题是三元运算符是基于你的第一个参数赋值来推断类型的...在这种情况下是10,这是一个int,而不是一个可以为null的int .

    你可能会有更好的运气:

    int? x = GetBoolValue() (int?)10 : null;
    
  • 3
    int? x = GetBoolValue() ? 10 : (int?)null;
    

    你看到这个的原因是因为幕后你正在使用Nullable,你需要告诉C#你的“null”是Nullable的null实例 .

  • 3

    只需添加一个explict演员 .

    int? x = GetBoolValue() ? 10 : (int?)null;
    

    这是三元运算符混淆 - 第二个参数是一个整数,所以第三个参数也是一个整数,并且null不适合 .

  • 4

    这是因为编译器通过它的第二个和第三个操作数来确定条件运算符的类型,而不是通过将结果赋给的值来确定 . 整数和空引用之间没有直接强制转换,编译器可以使用它来确定类型 .

相关问题