枚举可以在C#中返回一个新实例吗?

时间:2011-05-17 22:12:02

标签: c# enums factory

向大家致以问候!

我会尝试简单地解决问题:我有一个enum来选择我应该使用哪个ObjTypeObjTypeAObjTypeB都继承自{{1} }})。所以我创建了一个扩展给定ObjType的方法,以便根据enum中的selected属性返回一个新实例,如下代码所示。我认为它或多或少像工厂设计模式。到目前为止一直很好,但最终,就像在课程enum中一样,我可能会尝试创建MyClassn的{​​{1}}个实例,但我必须面对每当我调用ObjTypeA方法时,ObjTypeB语句。所以:

  • if可以返回一个实例,例如:GetObjTypeInstance()吗?实际上,最好将enum方法添加到public enum EObjType { ObjTypeA = new ObjTypeA(), ObjTypeB = new ObjTypeB() }中的GetInstance()ObjTypeA选项中。如果有办法做到这一点,我该怎么办?这样做我每次步骤都会避免使用if语句。
  • 有没有其他(更好)的方法(如果你理解我的问题......)?怎么样?

提前致谢!

按照示例代码:

ObjTypeB

7 个答案:

答案 0 :(得分:3)

你必须把这个苹果放在某个地方。

也许用if/elseif语句替换switch链,它们与枚举效果很好。

答案 1 :(得分:2)

我不会使用enum,而是使用类似枚举的类:

public class EObjType {
    public static readonly EObjType ObjTypeA = new EObjType(() => (ObjType)(new ObjTypeA));
    public static readonly EObjType ObjTypeB = new EObjType(() => (ObjType)(new ObjTypeB));

    private readonly Func<ObjType> generator;
    private EObjType(Func<ObjType> generator) {
        this.generator = generator;
    }

    public ObjType GetInstanceOfObjType() {
        return generator();
    }
}

然后,您可以像使用枚举一样使用它。

EObjType otEnum = EObjType.ObjTypeA;
ObjType obj = otEnum.GetInstanceOfObjType();

答案 2 :(得分:1)

您需要使用工厂或其他创作设计模式。

例如,您可以使用枚举键保存字典以键入值,以使用选定的枚举值获取所需的类类型。然后使用反射创建接收类型的新实例(对象)。

使用工厂类的静态构造函数初始化静态字典的值。您可以手动或更好地输入值,从配置文件中加载可能的值。

答案 3 :(得分:1)

我不确定我是否真的提倡这种方法,但你可以调用enum ToString()方法,将其视为你的类名并使用反射来实例化一个对象类型。

这样做的一个优点是你可以反映并获得一次类型,然后在循环中调用构造函数 n 次。

答案 4 :(得分:1)

正如Danny Varod指出的那样,将枚举值映射到其类型(或创建这些类型的函数)的字典将允许您避免使用if语句。由于枚举实际上只是一个整数,因此数组的内存和时间效率会更高,但可读性在这里可能是最重要的。

答案 5 :(得分:1)

您可以创建一个工厂,允许注册映射到枚举的函数,您可以使用某种注册过程来注册不同的枚举

public class ObjectFactory
{
    private readonly Dictionary<MyObjectType, Func<MyObject>> _store = new Dictionary<MyObjectType, Func<MyObject>>();

    public void Register<T>(MyObjectType type) where T: MyObject, new()
    {            
        this.Register(type, () => new T());
    }

    public void Register(MyObjectType type, Func<MyObject> factory)
    {
        _store.Add(type, factory);
    }

    public MyObject CreateInstance(MyObjectType type)
    {
        Func<MyObject> factory;
        if(_store.TryGetValue(type, out factory))
        {
            return factory.Invoke();
        }
        return null;
    }
}

public enum MyObjectType { A, B }

public class MyObject {}

public class MyObjectA : MyObject {}
public class MyObjectB : MyObject {}

用法如下

var factory = new ObjectFactory();
factory.Register<MyObjectA>(MyObjectType.A);
factory.Register<MyObjectB>(MyObjectType.B);

var a = factory.CreateInstance(MyObjectType.A);
var b = factory.CreateInstance(MyObjectType.B);

Assert.IsInstanceOf(typeof(MyObjectA), a);
Assert.IsInstanceOf(typeof(MyObjectB), b);

答案 6 :(得分:1)

您可以使用Activator.CreateInstance。

public class ObjType {}
public class ObjTypeA : ObjType {}
public class ObjTypeB : ObjType {}
public enum EObjType { ObjTypeA, ObjTypeB }

public static class EObjTypeExt
{
    public static ObjType GetObjTypeInstance( EObjType ot)
    {
        object o = Activator.CreateInstance(null,ot.ToString());
        return (ObjType)o;
    }
}
相关问题