代码之家  ›  专栏  ›  技术社区  ›  Ryan

强类型枚举类型的方法参数

c#
  •  3
  • Ryan  · 技术社区  · 14 年前

    考虑以下代码

    enum HorizontalAlignment { Left, Middle, Right };
    enum VerticleAlignment { Top, Middle, Bottom };
    
    function OutputEnumValues (Type enumType)
    {
        foreach (string name in Enum.GetNames(typeof(enumType)))
        {
            Console.WriteLine(name);
        }
    }
    

    可以称之为

    OutputEnumValues (typeof(HorizontalAlignment));
    OutputEnumValues (typeof(VerticleAlignment ));
    

    但我可以随便打个电话,比如说

    OutputEnumValues (typeof(int));
    

    这将编译,但在运行时失败枚举.GetNames()

    有没有编写方法签名以在编译时捕获这类问题的方法-即只接受OutputEnumValues中的枚举类型?

    4 回复  |  直到 14 年前
        1
  •  4
  •   Timwi    14 年前

    0 它将成为一个静态类型化为枚举的值。

    此外,您可以有一个类型为 Enum

    public static void OutputEnumValues(Enum example)
    {
        foreach (string name in Enum.GetNames(example.GetType()))
        {
            Console.WriteLine(name);
        }
    }
    

    OutputEnumValues((HorizontalAlignment) 0);
    OutputEnumValues((VerticalAlignment) 0);
    

        2
  •  1
  •   Community noseratio    7 年前

    这里真正需要的是一个可以约束到枚举类型的泛型方法。然而,这在C#中是不可能的。

    Jon Skeet对此问题有一个答案: Anyone know a good workaround for the lack of an enum generic constraint?

    对于你的方法你真正想要的是

    public void OutputEnumValues<T>() where T : HorizontalAlignment
    {
        foreach (string name in Enum.GetNames(typeof(T)))
        {
            Console.WriteLine(name);
        }
    }
    

    但这种限制是行不通的,除非你采纳乔恩的建议。

        3
  •  1
  •   Mark Byers    14 年前

    我认为这在C中是不可能的。

    您可以改为在Enum上使用扩展方法,但这将要求您在实例上调用它,而不是在可能不需要的类型本身上调用它。

    public static void OutputValues<T>() where T : struct
    {
        if (!typeof(T).IsEnum)
            throw new NotSupportedException("Argument must be an enum.");
    
        // code here...
    }
    

    如果试图用类调用它,则会出现编译时错误;如果用非枚举的结构调用它,则会出现运行时错误。

        4
  •  0
  •   Ed Swangren    14 年前

    我看不出你所说的“问题”。

    同样,方法的名称使得参数应该是枚举值这一点非常明显。你可以认为这是一个契约,如果代码的客户违反了这个契约,那么它就会在他们面前爆炸。任何API都包含可以向其发送坏数据的方法。