Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Nullable<T> use it's underlying value type extension method

One hour ago I asked a question: how can I write an extension method for Enum?-Nullable<Enum>
surprisingly I got an answer telling me I can write the extension method for Enum and it can be used for all enums and nullable enums.

Cool, it workes, but how?

If I understand correctly, all enums derive from Enum so this why I can use this extension method in every enum I have.

But... the ItemType? enum, for example, isn't an enum, it's Nullable<ItemType>, which doesn't derives from ItemType nor Enum.
Just like List<DataReader> doesn't derive from DataReader and thus can't use DataReader methods, though DataReader is it's Generic type.

I know The Nullable<T> type has a lot of "voodoo" and syntactic sugar, is this one of them?

like image 626
gdoron is supporting Monica Avatar asked Feb 18 '23 19:02

gdoron is supporting Monica


2 Answers

Extension methods do not require the class to be /derived/, they just require a conversion to exist (more specifically: an implicit identity, reference or boxing conversion; this is §7.6.5.2 "Extension method invocations").

The conversion from Nullable<ItemType> to System.Enum is a boxing conversion; same as a conversion from Nullable<int> to System.Object.

And if you defined your own structure struct Test : IMyInterface {}, there would be a conversion from Nullable<Test> to IMyInterface.

Boxing conversions from nullables will return a null reference if the nullable was null; and box the nullable's value otherwise. For details see §6.1.7 "Boxing conversions" in the C# specification.

like image 188
Daniel Avatar answered Feb 21 '23 16:02

Daniel


It's more type system magic than compiler magic. Since Enum is a reference type this means that any value you pass in will get boxed (e.g. converted to a reference).

Now Nullable<T> has the special handling in the CLR that boxing it will yield wither null if it represents a null value or a boxed value of the inner type (T), but never a boxed Nullable<T>. Of course, the opposite is true as well; unboxing to a nullable type accepts a null reference.

like image 44
Lucero Avatar answered Feb 21 '23 18:02

Lucero