C# 对另一个泛型扩展方法的参数调用泛型扩展方法

C# 对另一个泛型扩展方法的参数调用泛型扩展方法,c#,.net,asp.net-mvc-3,C#,.net,Asp.net Mvc 3,我正在做一些ASP.NET MVC 3,我正在为使用枚举设置一些扩展方法。其中一个是查找[Description]属性的fancy ToString,另一个是从枚举中构建一个SelectList,用于Html.DropDownList。这两个方法都在同一个静态类中 public static SelectList ToSelectList<TEnum>(this TEnum? enumval) where TEnum : struct { var values = from

我正在做一些ASP.NET MVC 3,我正在为使用枚举设置一些扩展方法。其中一个是查找[Description]属性的fancy ToString,另一个是从枚举中构建一个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的核心转移到一个私有静态方法中来实现这一点,并使扩展方法成为该方法的包装器,但是链接通用扩展方法似乎是我应该知道如何正确完成的事情;它只是一个结构。GetDescription采用可为空的结构


要么使e可为null,要么使GetDescription的版本不可为null。

使用null作为参数有什么特殊原因吗?我很难理解为什么要对空值调用这些扩展方法

如果您消除了可为null的要求,则可以使它们成为非泛型的,并直接基于枚举类型,这更为友好,包括允许您以通常的方式对枚举值使用扩展方法语法:

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();

是的,我是个笨蛋。我从TEnum e变为TEnum e?这让我走了。谢谢。@ChamikaSandamal让我等了大约10分钟才做标记。变量e是TEnum类型。GetDescription扩展方法用于Nullable,而不是TEnum。你能让GetDescription成为一个不可为空的TEnum扩展吗?在这种情况下,我实际上使用了一个可为空的枚举。枚举表示项目任务项状态需要、不需要、已寻址…,空值表示尚未设置。但我喜欢这样清理代码;我会考虑在EnUM中添加一个未设置的值,这样做。我现在只是在做界面原型,所以现在改变还为时过早。明白了。如果可以的话,我总是喜欢保持一般性,以防万一有一天我使用的是不可为空的枚举版本。我想没有理由不能同时拥有两个版本的扩展方法。