2014-09-24 87 views
0

我有这样的代码如何安全地使用枚举重载构造函数? C#

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可能是创建。

+1

我认为这是足够安全的。由于您正在使用'MyEnumOne'和'MyEnumTwo'作为参数类型。您是否收到任何模糊呼叫的警告? – Habib 2014-09-24 14:40:36

+0

或者你是否担心使用只存在于E2中的*值*来调用'CreateWithE1'? – Rawling 2014-09-24 14:42:03

+0

它怎么可能*不*使用正确的构造函数超载?如果你传入一个类型为“MyEnumOne”的对象,它怎么可能调用MyEnumTwo重载?如果您尝试显式调用该重载(通过移除其他重载),它甚至不会编译。 – Servy 2014-09-24 14:42:44

回答

4

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

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

当这些方法之一是称为,构造函数的使用已经被固定在适当位置,而不是基于运行值参数的

+0

太棒了!这解决了这个问题=) – 2014-09-24 14:49:53

0

当调用任何带有implicit转换的重载方法时,因为存在int和enum之间,编译器会根据可转换类型推导出您想要的方法,就像直接调用方法时一样。但是,如果它遇到一个模棱两可的问题,那么它会抛出这个错误 - “模糊的匹配”。

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

如果你想避免工厂方法,你可以做以下

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

确保在显性和隐性的转换阅读起来,编译器如何解析重载。

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); 
} 

与其他转换类似。

+0

对不起,如果有人得到了错误的方式。我不想从E1到E2或反之亦然。我想要的是调用正确的构造函数,无论调用该函数的人是否使用该函数而没有足够明确,但无论如何要感谢;) – 2014-09-24 15:00:12