枚举扩展方法 - ToDataSource

时间:2009-09-08 18:00:36

标签: c# asp.net enums

我试图在枚举中添加一个扩展方法,将其转换为DataTable,以便它可以绑定到DropDownList,它可以正常工作。


public enum Response
{
    Yes = 1,
    No = 2,
    Maybe = 3
}

public static DataTable ToDataSource(this Enum e) { Type type = e.GetType(); DataTable dt = new DataTable();
dt.Columns.Add("value", typeof(Int32)); dt.Columns.Add("text", typeof(String));

foreach (Int32 value in Enum.GetValues(type))
{
    dt.Rows.Add(new object[] { value, Enum.GetName(type, value) });
}

return dt;

}

但是有没有办法可以在枚举本身上使用扩展方法(Response.ToDataSource)而不必使用它挂起一个值Responce.Yes.ToDataSource?

我尝试过创建一个新实例(Response new response,response.ToDataSource但是我得到一个构建错误,说“在访问之前可能没有初始化”。

7 个答案:

答案 0 :(得分:4)

不幸的是你做不到。扩展方法是一种允许您在类型实例上调用新方法的外观的功能。它没有能力提供这种能力来自己打字。

当我想添加一组方法时,添加类型级别I通常会创建一个名为OriginalTypeNameUtil的新静态类,并在那里添加方法。例如ResponseUtil。这样,当我键入原始类型名称时,类名称是可见的。

答案 1 :(得分:2)

我只做类似的事情,而不是扩展Enum类型,我扩展了DataTable。

public static DataTable FromEnum(this DataTable dt, Type enumType) {
if (!enumType.IsEnum) { throw new ArgumentException("The specified type is not a System.Enum."); }
DataTable tbl = new DataTable();
string[] names = Enum.GetNames(enumType);
Array values = Enum.GetValues(enumType);
List<string> enumItemNames = new List<string>();
List<int> enumItemValues = new List<int>();
try {
    // build the table
    tbl.Columns.Add(new DataColumn("Value", typeof(string)));
    tbl.Columns.Add(new DataColumn("Text", typeof(string)));
    // Get the enum item names (using the enum item's description value if defined)
    foreach (string enumItemName in names) {
        enumItemNames.Add(((Enum)Enum.Parse(enumType, enumItemName)).ToDescription());
    }
    // Get the enum item values
    foreach (object itemValue in values) {
        enumItemValues.Add(Convert.ToInt32(Enum.Parse(enumType, itemValue.ToString())));
    }
    // Make sure that the data table is empty
    tbl.Clear();

    // Fill the data table
    for (int i = 0; i <= names.Length - 1; i++) {
        DataRow newRow = tbl.NewRow();
        newRow["Value"] = enumItemValues[i];
        newRow["Text"] = enumItemNames[i];
        tbl.Rows.Add(newRow);
    }
}
catch {
    tbl.Clear();
    tbl = dt;
}
// Return the data table to the caller
return tbl;

}

它被称为:

DataTable tbl = new DataTable().FromEnum(typeof(YourEnum));

答案 2 :(得分:1)

看起来你只想要一个真正的静态方法和一个“类似enum”的类:

public class Response
{
    public static readonly Response Yes = new Response(1);
    public static readonly Response No = new Response(2);
    public static readonly Response Maybe = new Response(3);

    int value;

    private Response(int value)
    {
        this.value = value;
    }

    public static DataTable ToDataSource()
    {
        // ...
    }
}

答案 3 :(得分:1)

如果使用模拟枚举的结构:

   public struct Response
   {
     private int ival;
     private Response() {} // private ctor to eliminate instantiation
     private Response(int val) { ival = val; }
     private static readonly Response Yes = new Response(1);
     private static readonly Response No = new Response(2);
     private static readonly Response Maybe= new Response(3);
     // etc...  ...for whatever other functionality you want.... 
   }

然后这个结构完全(接近完全!)就像一个枚举,你可以添加extensiuon方法...

答案 4 :(得分:1)

无法在枚举上创建扩展方法。

但是,您可以创建一个接受枚举并从中创建表的通用函数。

public static DataTable CreateDataSource<TEnum>()
{
    Type enumType = typeof(TEnum);

    if (enumType.IsEnum) // It is not possible to do "where TEnum : Enum"
    {
        DataTable table = new DataTable();
        table.Columns.Add("Name");
        table.Columns.Add("Value", enumType);

        foreach (var value in Enum.GetValues(enumType))
        {
            table.Rows.Add(Enum.GetName(enumType, value), value);
        }

        return table;
    }
    else
        throw new ArgumentException("Type TEnum is not an enumeration.");
}

答案 5 :(得分:0)

请记住,如果您选择实现“Enum-Class”的路线并发现自己处于不允许构造函数为私有的位置,则需要重写Equals和GetHashCode。

答案 6 :(得分:-1)

string[] names = Enum.GetNames(typeof(Test));

Array test = Enum.GetValues(typeof(Test));
var vals = test.Cast<int>();

var source = from n in names
             from v in vals
             select new
             {
                 Text = n,
                 Value = v
             };

未经测试但很快:)