long? i = 10000;
int? s = i as int?;
Why is it giving me a null in s
variable? I know that casting it using int? s = (int?)i;
will work fine but why can't I use an as
operator?
Conversion from a nullable value type to an underlying type At run time, if the value of a nullable value type is null , the explicit cast throws an InvalidOperationException.
A type is said to be nullable if it can be assigned a value or can be assigned null, which means the type has no value whatsoever.
As described above, The Nullable types used to assign the null value to the value data type. That means we can assign a null value directly to a variable of the value data type. We can declare null value using Nullable<T> where T is a type like an int, float, bool, etc.
Characteristics of Nullable Types Nullable types can only be used with value types. The Value property will throw an InvalidOperationException if value is null; otherwise it will return the value. The HasValue property returns true if the variable contains a value, or false if it is null. You can only use == and !=
From MSDN:
The code is equivalent to the following expression except that the expression variable is evaluated only one time.
expression is type ? (type)expression : (type)null
Since i is int?
is false the as
keyword will return (int?)null
.
The types aren't equivalent and you get null, that is just how as
works
However, you could just direct Cast
long? i = 10000;
var s = (int?)i;
// or even better make sure its *checked*
var s = checked((int?)i);
Why does this work?
C# Language Specification 11.6.1 Nullable Conversions
...
Evaluation of a nullable conversion based on an underlying conversion from S to T proceeds as follows:
- If the nullable conversion is from
S?
toT?
:- If the source value is null (
HasValue
property isfalse
), the result is thenull
value of typeT?
.- Otherwise, the conversion is evaluated as an unwrapping from
S?
toS
, followed by the underlying conversion fromS
toT
, followed by a wrapping fromT
toT?
....
as
does not do this, it checks the run-time types, if they are not equal returns null T?
Additional Resources
checked (C# Reference)
The checked keyword is used to explicitly enable overflow checking for integral-type arithmetic operations and conversions.
#Update from comments
I got that we can't convert and why we can't do I but why they are suggesting it is there any scenario where it will be useful i'e some random image link of Compiler Error CS0077 "The as operator must be used with a reference type or nullable type ('int' is a non-nullable value type)."
The reason is (in your image example) a value type can't be null it could never work with it. The thing you are missing is there are more complex examples of what could happen, you can define implicit operators on custom types, etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With