可以为空的枚举的扩展方法

时间:2012-10-18 14:25:08

标签: c# .net compiler-construction enums nullable

我正在尝试为可为空的枚举编写扩展方法 就像这个例子一样:

// 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?上收到以下错误:

  

只有非可空值类型可能是system.nullable

的基础

为什么呢?枚举不能具有值null

更新

如果有很多枚举,ItemType只是其中一个的示例。

4 个答案:

答案 0 :(得分:18)

System.Enumclass,所以只需删除?,这应该有用。

(通过“这应该有效”,我的意思是如果你传入一个空值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

答案 1 :(得分:3)

您应该在方法签名中使用实际的枚举类型:

public static string GetDescription(this ItemType? theEnum)

System.ValueTypeSystem.Enum不被视为值类型(仅从它们派生的类型),因此它们可以为空(并且不要将它们指定为可为空)。试试吧:

// No errors!
ValueType v = null;
Enum e = null;

你也可以尝试这个签名:

public static string GetDescription<T>(this T? theEnum) where T: struct

这也允许使用struct,这可能不是你想要的。我想我记得有些库在编译后添加了enum的类型约束(C#不允许它)。只需要找到它......

编辑:找到它:

http://code.google.com/p/unconstrained-melody/

答案 2 :(得分:1)

您可以简单地将扩展方法设为通用:

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,因此扩展方法将显示所有可空值(因此额外检查)。

答案 3 :(得分:0)

也许更好的是为你的枚举添加额外的值并将其称为null:)