Why can't a nullable int be implicitly conversion to an int ? Technical reason or design choice?

别等时光非礼了梦想. 提交于 2019-12-24 06:19:28

问题


In C#, there is no implicit conversion from the int? type to the int type.

I have defined the following implicit operator

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

Which allows me to compile the following code

int? nullableInt = 0;
Int32 regularInt = nullableInt;

but if I define regularInt as an int instead of Int32 I get the following error

Cannot implicitly convert type 'int?' to 'int'. An explicit conversion exists (are you missing a cast?)

I expected int and Int32 to be interchangeable but the C# language clearly hasn't been built with this functionality in mind.

Is there a technical reason behind the impossibility of defining this operation, is it a decision made to prevent potential code smell ?

I'm aware that defining such an implicit operator could result in some very unexpected behavior, as the conversion from a null value to a 0 integer doesn't make sense in every situation. This question is more about "why can't it be done" than "why doing it is a really bad idea"


回答1:


The code you have doesn't add an implicit conversion from the .NET's nullable int to .NET's int. It creates a whole new type, called Int32, in the System namespace, but as it's in a different assembly than Core.dll, it's a different type. (Take a look at typeof(int).FullName and typeof(int32).FullName to see this.)

The code you showed to try to test this implicit conversion is set up so that it's trying to convert the system's nullable type to your own new type, and since you created such an implicit conversion, it succeeds. It fails when you use the system type instead of your own new type because there is no implicit conversion between those types.

You cannot create implicit (or explicit) conversions for types from outside the definition of one of those types, and since you can't access the source of either Nullable or the .NET Int32, you can't add an implicit conversion.




回答2:


As documented here, implicit type conversions are only possible, as long as the conversion is save.

Example from before

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

In your case, int or Int32 may be savely converted to int? but not vice-versa.

The same applies to 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;



回答3:


Because the default value of int is 0 but int? by default has a null value which is not a valid int value and will result to an exception.

For instance, int x; // declaration result to 0 int? x; // declaration results to null (not valid int value)



来源:https://stackoverflow.com/questions/56345723/why-cant-a-nullable-int-be-implicitly-conversion-to-an-int-technical-reason-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!