我正在尝试为可为空的枚举编写一个扩展方法。
就像这个例子一样:
// ItemType is an enum
ItemType? item;
...
item.GetDescription();
所以我写了这个方法,但由于某种我不明白的原因而无法编译:
public static string GetDescription(this Enum? theEnum)
{
if (theEnum == null)
return string.Empty;
return GetDescriptionAttribute(theEnum);
}
我在
Enum?
上收到以下错误:
只有不可为 null 的值类型可以作为 system.nullable 的基础
为什么?枚举不能有值
null
!
更新:
如果有很多枚举,
ItemType
只是其中之一的示例。
System.Enum
是一个 class
,所以只需删除 ?
就可以了。
(“这应该有效”,我的意思是如果您传入一个空值
ItemType?
,您将在方法中得到一个 null
Enum
。)
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
您可以简单地使您的扩展方法通用:
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);
}
不幸的是,您不能在通用约束中使用
System.Enum
,因此扩展方法将为所有可为空的值显示(因此需要额外检查)。
编辑: C# 7.3 引入了新的泛型约束,现在允许将泛型参数限制为枚举,如下所示:
public static string GetDescription<T>(this T? theEnum) where T : Enum
{
if (theEnum == null)
return string.Empty;
return GetDescriptionAttribute(theEnum);
}
感谢@JeppeStigNielsen 指出了这一点。
您应该在方法签名中使用实际的枚举类型:
public static string GetDescription(this ItemType? theEnum)
System.ValueType
和 System.Enum
不被视为值类型(仅从它们派生的类型),因此它们可为空(并且您不要将它们指定为可为空)。尝试一下:
// No errors!
ValueType v = null;
Enum e = null;
您也可以尝试这个签名:
public static string GetDescription<T>(this T? theEnum) where T: struct
这也允许
struct
,但这可能不是你想要的。我想我记得一些库在编译后添加了 enum
的类型约束(C# 不允许)。只需要找到它...
编辑:找到它:
也许更好的是为您的枚举添加额外的值并将其称为 null :)