将受限类型传递给方法

4

这里有一些类似的问题,但似乎都没有完全回答我的问题。

我想创建一个方法,该方法接受一个枚举类型,并为UI生成一个ListItem列表。具有以下签名的方法可能有效:

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

但我宁愿不接受任何类型(t必须是枚举类型),这样我就可以像这样做:

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

您可以只将正确类型的枚举传递给该方法。这样做是可行的,但我真的想使用Type参数(就像我的第一个示例中那样),但强制它成为枚举类型。

这可能吗?是否可以使用泛型来实现? 谢谢


4
你可以看看http://code.google.com/p/unconstrained-melody/。即使Jon Skeet没有回答,Jon Skeet也会回答。他很有禅意。 - dlev
@dlev,你假设他现在没有回答。 - Anthony Pegram
2个回答

6
截止到C# 7.3版本,现在已经可以实现此功能:点击链接
public static List<ListItem> ListItemsListFromEnum<T>() where T:System.Enum

注意,T将会被限制为枚举类型。请注意必须使用Enum类型,关键字enum将无法编译。
在以前的C#版本中,这是不可能的。
如果您不能使用该版本的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");
    }     
}

唯一的负面是你会得到一个运行时异常而不是编译时异常。

是的,那就是我想要的。我猜我将不得不在运行时检查。 - Erix

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()) 所做的事情。


我明白了,但是我想要编译时检查。 - Erix
1
@Erix:是的,我也遇到过这种情况,在很多地方我都想说“where T : Enum”,但在C#中目前还不能这样做。 - James Michael Hare

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接