使用Dictionary创建对象的新实例

时间:2015-04-15 05:58:26

标签: c# dictionary

我想知道是否可以使用Dictionary<string, MyType>作为对象工厂,换句话说,给定一个字符串&#34; Foo&#34;我想要检索Foo类的新实例。

private Dictionary<string, MyType> ClassDic = new Dictionary<string, MyType>()
{
     {"Foo", new Foo()},
     {"Bar", new Bar()},
     //many more

}

我基本上想要做的是替换大量的if语句,然后手动创建对象:

 if(line == "Foo") { Stuff.Add(new Foo() { ID = i }; }
 if(line == "Bar") { Stuff.Add(new Bar() { ID = i }; }

FooBar派生自同一基类)

这样的事情:

BaseClass myObject;
if(ClassDic.TryGetValue(line, out myObject))
{
     Stuff.Add(myObject);
     myObject.ID = i;
}

问题出在我的代码中,字典给了我一个对象的相同引用,所以属性覆盖(例如,如果我有300个对象,那么所有300个对象的ID都会相同(最后一个))。

我也对这个问题的其他方法持开放态度。

1 个答案:

答案 0 :(得分:8)

  

我想知道是否可以使用Dictionary作为对象工厂,换句话说,给定一个字符串“Foo”我想要检索我的Foo类的新实例。

如果你想创建一个 new 实例,我会建议使用这样的Dictionary<string, Func<MyType>>

private static readonly Dictionary<string, Func<MyType>> Factories =
    new Dictionary<string, Func<MyType>>()
{
     {"Foo", () => new Foo() },
     {"Bar", () => new Bar() },
}

然后你可以使用:

MyType x = Factories[name]();

话虽如此,如果键真的只是类的名称,你可以使用反射:

Type type = Type.GetType(name);
MyType x = (MyType) Activator.CreateInstance(type);

请注意,name必须是名称空间限定的类名,因此您可能需要将名称空间添加到您传递的名称之前。它也只会查找当前正在执行的程序集中的类型mscorlib;如果您需要其他程序集中的类型,您可以传入程序集限定名称,也可以在相关程序集上调用Assembly.GetType(name)