I'm trying to write an Extension method for nullable Enums.
Like with this example:
// ItemType is an enum
ItemType? item;
...
item.GetDescription();
So I wrote this method which doesn't compile for some reason that I don't understand:
public static string GetDescription(this Enum? theEnum)
{
if (theEnum == null)
return string.Empty;
return GetDescriptionAttribute(theEnum);
}
I'm getting the following error on Enum?
:
only non-nullable value type could be underlying of system.nullable
Why? Enum can not have the value null
!
Update:
If have lots of enums, ItemType
is just an example of one of them.
An enum is a "value" type in C# (means the the enum is stored as whatever value it is, not as a reference to a place in memory where the value itself is stored). You can't set value types to null (since null is used for reference types only).
Since it's not a class, it cannot be extended and its defined values are limited to a small set of primitive types ( byte , sbyte , short , ushort , int , uint , long , ulong ). For instance, sometimes it is very convenient to get the list of enum values and display it in a combobox.
We can extend the enum in two orthogonal directions: we can add new methods (or computed properties), or we can add new cases. Adding new methods won't break existing code. Adding a new case, however, will break any switch statement that doesn't have a default case.
Page { protected void Page_Load(object sender, EventArgs e) { EnumTest oEnumTest = new EnumTest(); oEnumTest.Name = ""; oEnumTest. MyColor = null; //??? } } }
System.Enum
is a class
, so just drop the ?
and this should work.
(By "this should work", I mean if you pass in a null-valued ItemType?
, you'll get a null
Enum
in the method.)
public static string GetDescription(this Enum theEnum)
{
if (theEnum == null)
return string.Empty;
return GetDescriptionAttribute(theEnum);
}
enum Test { blah }
Test? q = null;
q.GetDescription(); // => theEnum parameter is null
q = Test.blah;
q.GetDescription(); // => theEnum parameter is Test.blah
You can simply make your extension method generic:
public static string GetDescription<T>(this T? theEnum) where T : struct
{
if (!typeof(T).IsEnum)
throw new Exception("Must be an enum.");
if (theEnum == null)
return string.Empty;
return GetDescriptionAttribute(theEnum);
}
Unfortunately, you cannot use System.Enum
in a generic constraint, so the extension method will show for all nullable values (hence the extra check).
EDIT: C# 7.3 introduced new generic constraints which now allow restricting a generic argument to an enum, like so:
public static string GetDescription<T>(this T? theEnum) where T : Enum
{
if (theEnum == null)
return string.Empty;
return GetDescriptionAttribute(theEnum);
}
Thanks @JeppeStigNielsen for pointing that out.
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