我有一个程序,我使用的是一个维护通用类类型字典的管理器。我希望能够注册新类型(使用多态)并将其存储在字典中(使用基于整数的键),然后能够根据存储的类型创建新对象。这就是我所拥有的:
Dictionary<uint,GenericClass> mGenericLibrary = new Dictionary<uint,GenericClass>();
public GenericClass GetNewGenericType(uint id)
{
return mGenericLibrary[id];
}
字典将保存GenericClass类型的子类,即GenericClassSub1,GenericClassSub2,GenericClassSub3等....
此时我想在另一个类中调用GetNewGenericType并根据注册的整数ID获取一个属于其中一个子类型的新对象。
我该怎么做?
答案 0 :(得分:2)
您要做的是“Factory Pattern”。而不是包含您想要创建的类型的字典,而是使用字典保存类来生成您想要创建的类型(“工厂”)。
public abstract GenericFactory
{
public abstract GenericClass CreateInstance();
}
public GenericClassSub1Factory : GenericFactory
{
public override GenericClass CreateInstance()
{
return new GenericClassSub1();
}
}
public GenericClassSub2Factory : GenericFactory
{
public override BaseClass CreateInstance()
{
return new GenericClassSub2();
}
}
然后你声明你的字典并像这样使用它:
class MyClassFactory
{
Dictionary<uint,GenericFactory> mGenericLibrary = new Dictionary<uint,GenericFactory>();
public void RegisterFactory(uint id, GenericFactory factory)
{
mGenericLibrary[id] = factory;
}
public GenericClass GetNewGenericType(uint id)
{
return mGenericLibrary[id].CreateInstance();
}
}
void Example()
{
var factory = new MyClassFactory();
factory.RegisterFactory(1, new GenericClassSub1Factory());
factory.RegisterFactory(2, new GenericClassSub2Factory());
factory.RegisterFactory(3, new GenericClassSub3Factory());
var item1 = factory.GetNewGenericType(1); //Contains a new GenericClassSub1;
var item2 = factory.GetNewGenericType(2); //Contains a new GenericClassSub2;
var item3 = factory.GetNewGenericType(3); //Contains a new GenericClassSub3;
}
更新:
如果您不想让人们制作工厂类,您仍然可以通过委托来完成工厂模式,最终用户需要更少的代码才能添加到工厂。
class MyClassFactory
{
Dictionary<uint,Func<GenericClass>> mGenericLibrary = new Dictionary<uint,Func<GenericClass>>();
public void RegisterFactory(uint id, Func<GenericClass> factory)
{
mGenericLibrary[id] = factory;
}
public GenericClass GetNewGenericType(uint id)
{
//This could be one line, but i think mGenericLibrary[id]() looks too weird.
Func<GenericClass> factory = mGenericLibrary[id];
return factory();
}
}
void Example()
{
var factory = new MyClassFactory();
factory.RegisterFactory(1, () => new GenericClassSub1());
factory.RegisterFactory(2, () => new GenericClassSub2());
factory.RegisterFactory(3, () => new GenericClassSub3());
var item1 = factory.GetNewGenericType(1); //Contains a new GenericClassSub1;
var item2 = factory.GetNewGenericType(2); //Contains a new GenericClassSub2;
var item3 = factory.GetNewGenericType(3); //Contains a new GenericClassSub3;
}