object to struct with as operator
Because as
operator returns null
if type check fails:
The expression of the form
E as T
whereE
is an expression that returns a value andT
is the name of a type or a type parameter, produces the same result as:E is T ? (T)(E) : (T)null
except thatE
is only evaluated once.
Which can't be done if T
is non-nullable value type (so compiler emits the error). Using nullable value type as T
will work:
object actionData = new Hex(); // your code returning boxed Hex
Hex? hex = actionData as Hex?;
if(hex.HasValue)
{
...
}
Case 1
Assuming that the result of GetData()
is of correct the correct type (ie something that is castable to the Hex
struct the following will successfully compile and also work at runtime
struct Hex { ...}
...
Hex foo = (Hex)GetData();
because you can always write an explicit cast (ie you are telling the compiler you know what you are doing and it shouldn't care about possible incompatibilities)
Case 2
If the result of GetData()
is something, that isn't castable to Hex
the same code
struct Hex { ...}
...
Hex foo = (Hex)GetData();
will still successfully compile (because you are overruling the compiler). But it will throw an InvalidCastException
at runtime.
Case 3
Your second snippet won't even compile. Because the result of the as
operator is nullable (ie as
returns null
if the typecheck fails) and you cannot assign null
to a non-nullable struct.
struct Hex { ...}
...
Hex hex = actionData as Hex;
If you want to be able to compile this, you have to make the variable nullable like
Hex? hex = actionData as Hex?;
if (hex.HasValue) {
... //conversion succeeded
} else {
... //conversion failed and hex is null
}
or you make Hex
a class
instead of a struct
. Because a class
is a reference type which can also be null
, but a struct
is a value type which cannot be null.