如何使用枚举安全地重载构造函数? C#

时间:2014-09-24 14:37:36

标签: c# constructor enums overloading

我有这段代码

public enum MyEnumOne : byte { ... }
public enum MyEnumTwo : byte { ... }

public class MyClass
{
    public readonly MyEnumOne E1;
    public readonly MyEnumTwo E2;

    private MyClass(MyEnumOne e1)
    {
        E1 = e1;
    }

    private MyClass(MyEnumTwo e2)
    {
        E2 = e2;
    }

    public static MyClass CreateWithE1(MyEnumOne e1)
    {
        return new MyClass(e1);
    }

    public static MyClass CreateWithE2(MyEnumTwo e2)
    {
        return new MyClass(e2);
    }
}

如何确保此代码始终会转换正确的构造函数重载?

var A = MyClass.CreateWithE1(0);
var B = MyClass.CreateWithE2(0);

我可以通过使类可变来确保这一点,但我不需要该类是可变的。

注意:如果我犯了任何错误,让课程不变,请告诉我:)

编辑:两个枚举都有None = 0的第一个元素,并且存在可以创建枚举到None的实例的合法情况。

3 个答案:

答案 0 :(得分:4)

CreateWithE1 编译时,它包含对基于MyEnumOne的构造函数的调用。

同样,当CreateWithE2 编译时,它包含对基于MyEnumTwo的构造函数的调用。

当这些方法中的任何一个被称为时,要使用的构造函数已经就位,并且不是基于参数的运行时

答案 1 :(得分:0)

当使用implicit转换调用任何重载方法时,因为在int和enum之间,编译器会根据可转换类型推断出所需的方法,就像直接调用方法时一样。但是,如果它遇到歧义,那么它就会抛出那个错误 - “模棱两可的匹配。”

因此,上述构造函数是安全的,但会强制任何实现指定显式他们想要传递的类型,因此编译器可以正确推断。但是,由于您的方法采用特定的枚举,它们可以与编译器区分开来,使得上面的代码可以毫无问题地通过编译器。

如果您想避开工厂方法,可以执行以下操作

var A = new MyClass((MyEnumOne)0);
var B = new MyClass((MyEnumTwo)0);

确保阅读显式和隐式转换,以及编译器如何解决重载。

答案 2 :(得分:0)

以最安全的方式实现的方法如下:

l_param.DbType =(DbType)Enum.Parse(typeof(DbType),param.dataType);

public readonly MyEnumOne E1;
public readonly MyEnumTwo E2;

private MyClass(MyEnumOne e1)
{
    E1 = (MyEnumTwo)Enum.Parse(typeof(MyEnumTwo), e1);
}

与其他转换类似。