问题
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