在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”。存在显式转换(您是否缺少演员表?)
我希望Int32
和int
可以互换,但显然C#语言并不是在考虑此功能的情况下构建的。
无法定义此操作背后是否有技术原因,是否已做出决定以防止潜在的代码气味?
我知道定义这样的隐式运算符可能会导致某些非常意外的行为,因为从Int32
值到null
整数的转换并非在每种情况下都有意义。这个问题更多的是关于“为什么不能做到”而不是“为什么这样做是一个真的坏主意”
答案 0 :(得分:11)
您拥有的代码没有添加从.NET的可为null的int到.NET的int的隐式转换。它在Int32
名称空间中创建了一个全新的类型,称为System
,但是由于它与Core.dll位于不同的程序集中,因此它是另一种类型。 (看看typeof(int).FullName
和typeof(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;
在您的情况下,int
或Int32
可能会轻松地转换为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值)