如何动态创建派生对象的集合?

时间:2011-12-05 20:17:19

标签: c#-4.0 dynamic collections derived-class

此问题似乎已经得到了回答,但我无法找到我需要的内容。这是我的情况:

// Base class
interface IAnimal {};
public abstract class Animal : IAnimal{}

// Derived classes
interface IDog {}
public class Dog : Animal, IDog { }
interface ICat { }
public class Cat : Animal, ICat { }
interface ITiger { }
public class Tiger : Animal, ITiger { }
interface ILion { }
public class Lion : Animal, ILion { }

// Collection Classes
interface IPets { }
public class Pets
{
    IDog dog = new Dog();
    ICat cat = new Cat();
}
interface ICircus { }
public class Circus
{
    ITiger tiger = new Tiger();
    ILion lion = new Lion();
}

我想在一个通用的Event类中运行时创建集合,方法是读取构成集合的xml列表中的动物。实现这一目标的正确方法是什么?

提前致谢。

2 个答案:

答案 0 :(得分:1)

这是对我自己的问题的回答。也许这会有所帮助。

我选择了一个非常通用的例子来说明我的情况,因为我在Windows Forms,XNA和Silverlight中的许多地方都有这种用法,它们都非常不同。

当我使用Activator时,我发现它假设执行程序集。我的方法在库中,所以我不得不加载一个不同的程序集。接下来我必须确保我有正确的命名空间。我的基类位于库中,派生类位于另一个名称空间中,因此需要重构才能正确创建列表。

我发现的另一个问题是Activator假定一个没有参数的构造函数。在我的测试用例中,我所有的派生类都是XNA游戏组件,其参数类型为Game。

必须进行一些重构来测试接口以及游戏对象的交互方式。

当我有更进一步的东西时,将回到此列表。

答案 1 :(得分:0)

这种示例有帮助吗? (这是我的一些代码,我碰巧得到了方便。)这里的关键点是在Activator.CreateInstance(...)中使用反射。

public static List<dynamic> LoadChildEntities(XElement entityElt)
{
    var children = new List<dynamic>();

    foreach(XElement childElt in entityElt.Elements("entity"))
    {
        // Look up the C# type of the child entity.
        string childTypename = "MyNamespace." + Convert.ToString(childElt.Attribute("type").Value);
        Type childType = Type.GetType(childTypename);

        if(childType != null)
        {
            // Construct the child entity and add it to the list.
            children.Add(Activator.CreateInstance(childType, childElt));
        }
        else
        {
            throw new InvalidOperationException("No such class: " + childTypename);
        }
    }

    return children;
}

如果您想要一个IAnimal的列表,那么改变它就不会太棘手。