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

如何安全地用枚举重载构造函数?C#,c#,constructor,enums,overloading,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

我有这个密码

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
的实例。

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

类似地,当编译
CreateWithE2
时,它包含对基于
MyEnumTwo
的构造函数的调用


调用这两个方法中的任何一个时,要使用的构造函数已经固定到位,并且不是基于参数的运行时值。

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

类似地,当编译
CreateWithE2
时,它包含对基于
MyEnumTwo
的构造函数的调用


调用这两个方法中的任何一个时,要使用的构造函数都已固定到位,并且不基于参数的运行时值。

调用任何重载方法并进行转换时,因为int和enum之间存在,编译器根据可转换类型推断出所需的方法,就像直接调用方法一样。但是,如果它遇到歧义,那么它将抛出错误——“歧义匹配”

因此,上述构造函数是安全的,但会强制任何实现显式指定它们要传入的类型,以便编译器能够正确推断。但是,由于您的方法接受特定的枚举,因此编译器可以区分它们,从而使上述代码无问题地通过编译器

如果要避免使用工厂方法,可以执行以下操作

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

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

当通过转换调用任何重载方法时,由于int和enum之间存在差异,编译器会根据可转换类型推断所需的方法,就像直接调用方法一样。但是,如果它遇到歧义,那么它将抛出错误——“歧义匹配”

因此,上述构造函数是安全的,但会强制任何实现显式指定它们要传入的类型,以便编译器能够正确推断。但是,由于您的方法接受特定的枚举,因此编译器可以区分它们,从而使上述代码无问题地通过编译器

如果要避免使用工厂方法,可以执行以下操作

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

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

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

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


同样,对于其他转换。

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

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


另一种转换也是如此。

我认为它足够安全。因为您正在使用
MyEnumOne
MyEnumTwo
作为参数类型。您是否收到任何关于不明确调用的警告?或者您是否担心使用仅存在于
E2
中的值调用
CreateWithE1
?它怎么可能不使用正确的构造函数重载?如果您将键入的对象传递给
MyEnumOne
它怎么可能调用
MyEnumTwo
重载?如果您试图显式调用该重载(通过删除另一个重载),它甚至不会编译。@TimSchmelter这些方法有不同的名称,因此从一开始就没有删除的风险。如果他试图重载一个方法/构造函数,他会得到一个编译时模糊错误,你只是用一个运行时错误来掩盖它。喜欢失败的工厂-还可以添加一个
[过时的(“不要用int调用”,true)]
来导致编译器失败。我认为这是足够安全的。因为您正在使用
MyEnumOne
MyEnumTwo
作为参数类型。您是否收到任何关于不明确调用的警告?或者您是否担心使用仅存在于
E2
中的值调用
CreateWithE1
?它怎么可能不使用正确的构造函数重载?如果您将键入的对象传递给
MyEnumOne
它怎么可能调用
MyEnumTwo
重载?如果您试图显式调用该重载(通过删除另一个重载),它甚至不会编译。@TimSchmelter这些方法有不同的名称,因此从一开始就没有删除的风险。如果他试图重载一个方法/构造函数,他会得到一个编译时模糊错误,你只是用一个运行时错误来掩盖这个错误。喜欢失败的工厂-还要添加一个
[过时的(“不要用int调用”,true)]
来导致编译器失败。如果有人用错误的方式得到了它,我很抱歉。我不想从E1解析到E2或反之亦然。我想要的是调用正确的构造函数,不管调用该函数的人是否使用了该函数,但还是要感谢;)对不起,如果有人弄错了。我不想从E1解析到E2或反之亦然。我想要的是调用正确的构造函数,不管调用该函数的人是否使用了该函数,但还是要感谢;)