为什么不能将可为null的int隐式转换为int?技术原因还是设计选择?

时间:2019-05-28 15:40:30

标签: c# implicit-conversion

在C#中,没有从@x类型到int?类型的隐式转换。

我已经定义了以下隐式运算符

int

哪些可以让我编译以下代码

namespace System
{
    public partial struct Int32
    {
        public static implicit operator Int32(int? v)
        {
            return (Int32)(v ?? 0);
        }
    }
}

但是如果我将int? nullableInt = 0; Int32 regularInt = nullableInt; 定义为regularInt而不是int,则会出现以下错误

  

无法隐式转换类型'int?'到“ int”。存在显式转换(您是否缺少演员表?)

我希望Int32int可以互换,但显然C#语言并不是在考虑此功能的情况下构建的。

无法定义此操作背后是否有技术原因,是否已做出决定以防止潜在的代码气味?

我知道定义这样的隐式运算符可能会导致某些非常意外的行为,因为从Int32值到null整数的转换并非在每种情况下都有意义。这个问题更多的是关于“为什么不能做到”而不是“为什么这样做是一个真的坏主意”

3 个答案:

答案 0 :(得分:11)

您拥有的代码没有添加从.NET的可为null的int到.NET的int的隐式转换。它在Int32名称空间中创建了一个全新的类型,称为System,但是由于它与Core.dll位于不同的程序集中,因此它是另一种类型。 (看看typeof(int).FullNametypeof(int32).FullName来看到。)

您设置了显示用于测试此隐式转换的代码,以使其尝试将系统的可为null的类型转换为您自己的新类型,并且由于创建了这种隐式转换,因此成功。当您使用系统类型而不是您自己的新类型时,它会失败,因为这些类型之间没有隐式转换。

您无法从这些类型之一的定义之外为类型创建隐式(或显式)转换,并且由于无法访问Nullable或.NET Int32的源,因此无法添加隐式转换。

答案 1 :(得分:-1)

here所述,只有保存转换,才可以进行隐式类型转换。

以前的例子

// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647; 
long bigNum = num;

在您的情况下,intInt32可能会轻松地转换为int?,反之亦然。

类型层次结构也是如此

class A {}

class B : A {}

class C : A {}

A var1 = new A(); // Compiles
A var2 = new B(); // Compiles (implicit cast)
B var3 = new B(); // Compiles

// need for explicit cast because instance2 can could also be A or C
B var4 = (B) instance2;

// Throws InvalidCastException
C var5 = (C) instance2;

答案 2 :(得分:-2)

因为int的默认值为0但为int?默认情况下,其null值不是有效的int值,并且会导致异常。

例如, int x; //声明结果为0 诠释? X; //声明结果为null(无效的int值)