将约束类型传递给方法

时间:2011-10-26 14:10:45

标签: c# generics types .net-4.0

这里有一些类似的问题,但似乎没有一个问题可以解答我的问题。

我想创建一个采用Enum Type的方法,并为UI生成ListItem的List。像这样签名的东西可以起作用:

public static List<ListItem> ListItemListFromEnum(Type t)
{
    ...        
}

但我宁愿不接受任何类型(t必须是Enum类型) 所以我可以这样做:

public static List<ListItem> ListItemListFromEnum(Enum e)
{
    Type t = e.GetType();
}

并将正确类型的枚举传递给方法。这样可以正常工作,但我真的想要一个Type参数(如我的第一个例子中所示),但强制它为Enum类型。

这可能吗?有没有办法用泛型做到这一点? 感谢

2 个答案:

答案 0 :(得分:6)

如果你的意思是想要制作这样的方法:

public static List<ListItem> ListItemsListFromEnum<T>() where T:Enum

那么在C#中是不可能的。但是,Jon Skeet汇总了Unconstrained Melody,这增加了一些IL后处理的功能。似乎C#编译器遵循这些约束,它只是不能声明它们。

那就是说,如果那不是您想要的,您可以按原样接受Type并查看IsEnum属性。如果是,请抛出异常。

public static List<ListItem> ListItemListFromEnum(Type t)
{
    if (!t.IsEnum)
    {
        throw new ArgumentException("Type must be an enumeration", "t");
    }     
}

同样,您也可以使用通用语言

public static List<ListItem> ListItemListFromEnum<T>()
{
    if (!typeof(T).IsEnum)
    {
        throw new ArgumentException("Type must be an enumeration", "t");
    }     
}

唯一不利的是,您将获得运行时异常,而不是编译时异常。

答案 1 :(得分:1)

您可以接受Type,然后在该类型不是enum类型时抛出。这可能是最好的方法(直到C#允许通用类型占位符被Enum约束,如果有的话。)

public static List<ListItem> ListItemListFromEnum(Type t)
{
        if (!t.IsEnum)
        {
            throw new ArgumentException("The type passed in must be an enum type.");                
        }

        // ...
}

这就是C#本身对许多Enum类的静态方法(例如Enum.GetEnumNames())的作用。