【问题标题】:Why can't an array of enum be used for params Enum[]?为什么不能将枚举数组用于参数 Enum[]?
【发布时间】:2021-02-08 15:53:01
【问题描述】:

似乎对于整数,我可以传递一个数组或逗号分隔的整数。但是对于枚举,只有逗号分隔的枚举有效。为什么会这样?

    enum Animal { Dog, Cat, Mouse};
    void Caller()
    {
        int[] aaa = { 1, 2, 3 };
        Ints(1, 2, 3);
        Ints(aaa);

        Animal[] bbb = { Animal.Dog, Animal.Cat, Animal.Mouse };
        Enums(Animal.Dog, Animal.Cat, Animal.Mouse);
        //CS1503 Argument 1: cannot convert from 'Animal[]' to 'System.Enum'
        Enums(bbb);
    }

    void Ints(params int[] aaa)
    {
    }

    void Enums(params Enum[] aaa)
    {
    }

【问题讨论】:

    标签: c# enums


    【解决方案1】:

    问题在于Enum 不是描述enum 的“真实”类型,因为前者是一个类,而后者是某种普通的旧整数(您可以描述哪种整数你要)。更准确地说,Enum 是一个 enum 盒装。

    请注意,如果您让编译器构造正确的泛型数组类型,您仍然可以获得完整的功能,同时保持函数的泛型:

    void Enums<TEnum>(params TEnum[] aaa) where TEnum: Enum
    {
    }
    

    【讨论】:

    • 注意,如果你愿意,这仍然可以让你写Enums&lt;Enum&gt;(...)。如果你想禁止这种情况,只让TEnum 使用特定类型的枚举(而不是Enum),你可以使用where T : struct, Enum
    • 是否可以将函数保持为void Enums(params Enum[] aaa),并在调用者中以某种方式将枚举数组(假设调用者将其作为参数)转换为逗号分隔的枚举并将其传递给`Enums()`函数?我想这可能是不可能的,但我不确定。
    • @DamnVegetables 不是没有分配一个新的数组,不是。 Enum[] 中的每个元素在物理上与Animal[] 中的每个元素的大小可能不同,并且包含不同的信息,因此您不能只将一个数组视为另一个数组。您必须构造一个新数组,并将每个Animal 转换为Enum。另请注意,接受Enum[] 意味着每个元素都需要装箱,这意味着新的堆分配,这是不必要的昂贵。 @Blindy 的回答是最简单的也是最便宜的方法
    【解决方案2】:

    简短的回答是:

    因为,任何枚举都继承自Enum,但数组是协变的,但仅适用于类,而枚举不是。所以Animal[] 不继承自Enum[]

    因此,“逐个参数”传递枚举会利用继承来编译代码。

    【讨论】:

    • 的数组是协变的。 Enum 是类,而不是结构,intMyEnum 是结构
    • @Charlieface 当涉及到 CLR intrinsicsSystem.EnumSystem.DelegateSystem.Array 时,类型系统中有一些时髦的东西在运行t 由 CLR 继承模型正确表示,因此据我所知,说 System.Array 的类协方差规则同样适用于 System.Enum 值是不准确的。
    • @Dai object[] arr = new Enum[5]; 与任何其他类型的工作方式相同。但是object[] arr = new int[5]; 没有,object[] arr = new MyEnum[5]; 也没有,原因相同:它们是结构。奇怪的是,MSIL 会让你(可验证地)这样做:MyEnum[] arr = new int[5];,但 C# 不会。
    【解决方案3】:

    Animal 是您的枚举类型。修正后的功能:

    void Enums(params Animal [] aaa)
    {
    }
    

    【讨论】:

    • 我希望Enums() 函数接受任何枚举类型值,而不仅仅是一种枚举类型。那这不可能吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-17
    • 1970-01-01
    • 2017-06-09
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    相关资源
    最近更新 更多