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?
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.
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 (eg 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.
The extension method is translated to a static method for which the first argument is the variable on which the method was invoked.
In the Enum example, since Enum is a class (not a struct), then the extension method can accept either a concrete value of the enum (which usually is boiled down to an int), or null. therefore it works with nullable enums.
that same thing would not work for int? (Nullable). if you create an extension method for int, you would not be able to invoke it on a Nullable (it will tell you "cannot convert instance argument type Nullable to int)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.