我有一个类似的继承树:
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());
答案 0 :(得分: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());
}
您必须为此部分编写自己的复制方法才能正常工作。
答案 1 :(得分: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());
但我怀疑这不是你想要做的。
答案 2 :(得分: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;
}