从字典列表中返回一个新对象

时间:2014-01-21 15:59:43

标签: c# generics dictionary types polymorphism

我有一个程序,我使用的是一个维护通用类类型字典的管理器。我希望能够注册新类型(使用多态)并将其存储在字典中(使用基于整数的键),然后能够根据存储的类型创建新对象。这就是我所拥有的:

Dictionary<uint,GenericClass> mGenericLibrary = new Dictionary<uint,GenericClass>();

public GenericClass GetNewGenericType(uint id)
{
     return mGenericLibrary[id];
}

字典将保存GenericClass类型的子类,即GenericClassSub1,GenericClassSub2,GenericClassSub3等....

此时我想在另一个类中调用GetNewGenericType并根据注册的整数ID获取一个属于其中一个子类型的新对象。

我该怎么做?

1 个答案:

答案 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;
}