0

我有一个像这样的继承树:

BaseType
TypeA : BaseType
TypeB : BaseType
TypeC : BaseType

每个派生对象都有一个名为的变量objectName,用于定义该对象的名称。

我还有一个数组和一个列表,它们都包含BaseType对象以及从BaseType. 该数组在创建时存储了对象,同时列表为空以供将来使用:

BaseType[] arrayA = new BaseType[] { new TypeA(), new TypeB(), new TypeC(), }

List<BaseType> listA = new List<BaseType>;

我还有一个方法用于将数组中的对象添加到列表中:

public void AddToList(BaseType itemToAdd)
{
    if(itemToAdd.objectName == "Type A")
        {
        listA.Add(new TypeA());
    }
    else if(itemToAdd.objectName == "Type B")
        {
        listA.Add(new TypeB());
    }
    else if(itemToAdd.objectName == "Type C")
        {
        listA.Add(new TypeA());
    }
}

如何避免必须使用所有这些if命令?有一次我尝试过:

public void AddToList(BaseType itemToAdd)
{
    listA.Add( new itemToAdd());
}

这没有用。那么我该怎么做这样的事情呢?对象不断增长,我不想为if我添加的每个派生对象添加一个。我还应该提到,不确定这是否会对解决方案产生任何影响,我一直在使用文件夹来组织 .cs 文件。因此,我将所有派生类都放在一个名为“Types”的文件夹中,因此要创建该对象的新实例,我必须键入:

listA.Add(new Types.TypeA());
4

3 回答 3

2

好吧,我看到的第一件事是您正在实例化您的项目,而不仅仅是将项目传入

您是否正在尝试执行以下操作?

public void AddToList(BaseType itemToAdd)
{
    listA.Add(itemToAdd);
}


原因

public void AddToList(BaseType itemToAdd)
{
    listA.Add( new itemToAdd());
}

不起作用是因为itemToAdd不是类型,而是类型的变量BaseType。你不能new在上面使用关键字。这没有任何意义。


如果您尝试复制该项目,您可以执行以下操作。

public void AddToList(BaseType itemToAdd)
{
    listA.Add(itemToAdd.Copy());
}

您必须编写自己的复制方法才能使这部分工作。

于 2012-11-05T19:40:07.443 回答
1

为什么您的 AddToList 创建新对象而不是添加 itemToAdd?换句话说:

public void AddToList(BaseType itemToAdd)
{
    listA.Add(itemToAdd);
}

此外,对象类型不需要字符串。您可以使用以下方法获取任何对象的类型:

myObj.GetType();

您可以使用以下方法比较对象的类型typeof

if (myObj.GetType() == typeof(TypeA))

如果你真的,真的必须创建与 相同类型的新对象itemToAdd,那么你可以使用Activator.CreateInstance来避免所有这些类型检查:

listA.Add((BaseType)Activator.CreateInstance(itemToAdd.GetType());

但我怀疑这不是你想做的。

于 2012-11-05T19:41:02.783 回答
0

好吧,你可以根据传入的类类型创建一个工厂类来创建你想要的对象,并像这样使用它:

public void AddToList(BaseType itemToAdd)
{
    listA.Add(ItemFactory.Create(itemToAdd.objectName));
}

但是当然,这只是将问题推低了一个级别(但仍然提高了 AddToList 代码的可读性)。

我认为,要执行您真正要求的操作,要么执行您已经建议的操作:if-else 链(或者可能是开关)来创建正确类型的实例;或使用反射来新建一个动态选择的类的实例。

作为简单的例子:

BaseType Create(BaseType source)
{
    var constructor = source.GetType().GetConstructor(new Type[0]);
    return constructor.Invoke(new object[0]) as BaseType;
}
于 2012-11-05T19:47:25.950 回答