为什么不能将可为空的 int 隐式转换为 int ?技术原因还是设计选择?
Why can't a nullable int be implicitly conversion to an int ? Technical reason or design choice?
在 C# 中,没有从 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
而不是 Int32
我会收到以下错误
Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?)
我原以为 int
和 Int32
可以互换,但显然 C# 语言在构建时并未考虑到此功能。
无法定义此操作背后是否存在技术原因,是否是为了防止潜在的代码异味而做出的决定?
我知道定义这样一个隐式运算符可能会导致一些非常意外的行为,因为从 null
值到 0
整数的转换并不是在所有情况下都有意义.这个问题更多是关于 "why can't it be done" 而不是 "why doing it is a really bad idea"
您的代码没有添加从 .NET 的可空 int 到 .NET 的 int 的隐式转换。它在 System
命名空间中创建了一个名为 Int32
的全新类型,但由于它位于与 Core.dll 不同的程序集中,因此它是不同的类型。 (看看 typeof(int).FullName
和 typeof(int32).FullName
就知道了。)
您显示的用于测试此隐式转换的代码已设置为尝试将系统的可空类型转换为您自己的新类型,并且由于您创建了此类隐式转换,它成功了。当您使用系统类型而不是您自己的新类型时它会失败,因为这些类型之间没有隐式转换。
您无法为其中一种类型的定义之外的类型创建隐式(或显式)转换,并且由于您无法访问 Nullable
或 .NET Int32 的源代码,因此您可以' 添加隐式转换。
如文档所述here,隐式类型转换是唯一可能的,只要转换被保存。
之前的例子
// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
在您的情况下,int
或 Int32
可以安全地转换为 int?
而不是 vice-versa。
同样适用于type-hierarchy
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;
因为int的默认值是0但是int呢?默认情况下有一个 null 值,它不是有效的 int 值,将导致异常。
例如,
诠释 x; //声明结果为0
诠释? X; // 声明结果为 null(无效的 int 值)
在 C# 中,没有从 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
而不是 Int32
我会收到以下错误
Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?)
我原以为 int
和 Int32
可以互换,但显然 C# 语言在构建时并未考虑到此功能。
无法定义此操作背后是否存在技术原因,是否是为了防止潜在的代码异味而做出的决定?
我知道定义这样一个隐式运算符可能会导致一些非常意外的行为,因为从 null
值到 0
整数的转换并不是在所有情况下都有意义.这个问题更多是关于 "why can't it be done" 而不是 "why doing it is a really bad idea"
您的代码没有添加从 .NET 的可空 int 到 .NET 的 int 的隐式转换。它在 System
命名空间中创建了一个名为 Int32
的全新类型,但由于它位于与 Core.dll 不同的程序集中,因此它是不同的类型。 (看看 typeof(int).FullName
和 typeof(int32).FullName
就知道了。)
您显示的用于测试此隐式转换的代码已设置为尝试将系统的可空类型转换为您自己的新类型,并且由于您创建了此类隐式转换,它成功了。当您使用系统类型而不是您自己的新类型时它会失败,因为这些类型之间没有隐式转换。
您无法为其中一种类型的定义之外的类型创建隐式(或显式)转换,并且由于您无法访问 Nullable
或 .NET Int32 的源代码,因此您可以' 添加隐式转换。
如文档所述here,隐式类型转换是唯一可能的,只要转换被保存。
之前的例子
// Implicit conversion. A long can
// hold any value an int can hold, and more!
int num = 2147483647;
long bigNum = num;
在您的情况下,int
或 Int32
可以安全地转换为 int?
而不是 vice-versa。
同样适用于type-hierarchy
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;
因为int的默认值是0但是int呢?默认情况下有一个 null 值,它不是有效的 int 值,将导致异常。
例如, 诠释 x; //声明结果为0 诠释? X; // 声明结果为 null(无效的 int 值)