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

本文关键字:扩展 泛型 方法 调用 参数 另一个 | 更新日期: 2023-09-27 18:12:46

我正在做一些ASP。. NET MVC 3,我正在设置一些扩展方法来处理枚举。其中一个是一个奇特的ToString(),它查找[Description]属性,另一个是从enum中构建一个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()的枚举参数的有效扩展方法。我意识到我可以通过将GetDescription()的核心移动到私有静态方法中,并使扩展方法只是对其进行包装来实现此工作,但是链接通用扩展方法似乎是我应该知道如何正确做的事情。

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

e不是可空结构体;它只是一个结构体。GetDescription接受一个可空结构体

使e为空,或使GetDescription为非空版本

使用Nullable<TEnum>作为参数有什么特别的原因吗?我不明白为什么要在null值上调用这两个扩展方法。

如果您去掉了可空的要求,您可以使它们非泛型并直接基于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();