2012-10-18 176 views
9

我试图编写一个扩展方法可为空的枚举。
就像这个例子:可扩展枚举的扩展方法

// 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只是其中的一个例子。

回答

17

System.Enumclass,所以刚落?,这应该工作。

(通过“这应该工作”,我的意思是,如果你在一个空值ItemType?通过,你会在方法获得nullEnum

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 
+0

http://msdn.microsoft.com/en-us/library/system.enum.aspx – Jacek

+0

@Jacek你是什么意思? – Rawling

+0

@Jacek:我打算写这篇文章,但是我测试了它,它出乎意料地工作。 – Jens

0

也许更好的是增加额外的价值,你的枚举,并把它叫做空:)

+1

是的,我同意,一个Enum的值为“Undefined”或“Null”,或者更有意义。或者你可以将你的枚举包装在一个类中,如果你真的想要一个空值,那么将它变为null。 –

+2

咦?完全相反的是 - 只有值类型可以与'Nullable '一起使用。 'INullable'与相关性如何? –

+0

enum null不是选项。不在asp.net-MVC – gdoron

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小号,虽然,这可能不是你想要的。我想我记得一些库在编译后(C#不允许)添加类型约束enum。只需要找到它......

编辑:发现:

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

+0

如果有很多枚举,'ItemType'就是一个例子。我确信这很明显,对不起。 – gdoron

+0

哦,你添加的第二部分回答我的问题,谢谢。但是有没有办法克服这种奇怪的设计? – gdoron

+0

您可以使用通用约束,但C#不允许将枚举指定为约束。看到我的编辑解决方案。 – Botz3000

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

+0

这很好,因为它避免了拳击。如果你愿意,你也可以说'!theEnum.HasValue'。如果有人对'System.Enum'的泛型约束感兴趣,请阅读[枚举和委托的泛型约束](https://msmvps.com/blogs/jon_skeet/archive/2009/09/10/generic-constraints-for -enums和 - delegates.aspx)。 –