15

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

// 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

4 回答 4

20

System.Enum是 a class,所以只需删除 the ?,这应该可以工作。

(通过“这应该工作”,我的意思是如果你传入一个 null-valued 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
于 2012-10-18T14:31:09.533 回答
4

您可以简单地使您的扩展方法通用:

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 指出这一点。

于 2012-10-18T14:36:39.623 回答
3

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

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

不过,这也允许structs,这可能不是您想要的。我想我记得一些库添加了enum编译后的类型约束(C# 不允许它)。只需要找到它...

编辑:找到它:

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

于 2012-10-18T14:28:39.063 回答
0

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

于 2012-10-18T14:28:18.563 回答