在另一个通用扩展方法的参数上调用泛型扩展方法

时间:2013-05-08 14:41:22

标签: c# .net asp.net-mvc-3

我正在做一些ASP.NET MVC 3,我正在设置一些使用Enums的扩展方法。其中一个是花哨的ToString(),它查找[Description]属性,另一个是从枚举构建一个SelectList,用于Html.DropDownList()。这两种方法都属于同一个静态类。

public static SelectList ToSelectList<TEnum>(this TEnum? enumval) where TEnum : struct {
    var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = e.GetDescription() };
    SelectList list = new SelectList(values, "ID", "Name", enumval);
    return list;
}

public static string GetDescription<TEnum>(this TEnum? enumval) where TEnum : struct {
    //Some reflection that fetches the [Description] attribute, or returns enumval.ToString() if it isn't defined.
}

但是编译器对Name = e.GetDescription()发出警告,说明......

  

'TEnum'不包含'GetDescription'的定义,并且没有可以找到接受类型'TEnum'的第一个参数的扩展方法'GetDescription'(你是否缺少using指令或汇编引用?)

这并不是一个巨大的惊喜,但我不确定如何让编译器将GetDescription()识别为ToSelectList()的enumval参数的有效扩展方法。我意识到我可以通过将GetDescription()的内容移动到私有静态方法中来实现这项工作,并使扩展方法只是一个包装器,但链接泛型扩展方法似乎是我应该知道如何正确执行的事情。

2 个答案:

答案 0 :(得分:2)

e不是可以为空的结构;它只是一个结构。 GetDescription采用可以为空的结构。

使e可以为空,或者制作GetDescription的不可空版本。

答案 1 :(得分:0)

您使用Nullable<TEnum>作为参数的任何特殊原因?我很难想到你为什么要在空值上调用这些扩展方法中的任何一个。

如果你摆脱了可空的要求,你可以直接使用它们是非泛型的,并且基于Enum类型,这更友好(包括让你以通常的方式使用扩展方法语法和枚举值) :

public static SelectList ToSelectList(this Enum enumval)
{
  var values = from Enum e in Enum.GetValues(enumval.GetType()) select new { ID = e, Name = e.GetDescription() };
  SelectList list = new SelectList(values, "ID", "Name", enumval);
  return list;
}

public static string GetDescription(this Enum enumval)
{
  //Some reflection that fetches the [Description] attribute, or returns enumval.ToString() if it isn't defined.
}

然后你可以这样做:

MyEnum enumval = MyEnum.Whatever;
var list = enumval.ToSelectList();

...我认为您不能使用当前的通用版本 - 您必须使用以下命令调用它:

MyEnum enumval = MyEnum.Whatever;
var list = ((MyEnum?)enumval).ToSelectList();