Reputation: 1
I have an inheritance tree like so:
BaseType
TypeA : BaseType
TypeB : BaseType
TypeC : BaseType
Each derived object has a variable named objectName
that defines that object's name.
I also have an array and a list that both hold theBaseType
objects as well as any objects derived from BaseType
. The array has objects stored in it upon being created, meanwhile the list is empty for future use:
BaseType[] arrayA = new BaseType[] { new TypeA(), new TypeB(), new TypeC(), }
List<BaseType> listA = new List<BaseType>;
I also have a method that is used to add an object that is in the array to the list:
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());
}
}
How can I avoid having to use all of those if
commands? At one point I tried:
public void AddToList(BaseType itemToAdd)
{
listA.Add( new itemToAdd());
}
Which did not work. So how can I go about doing something like this? The objects are constantly growing and I don't want to have to put an if
for every derived object I add. I should also mention, not sure if this will have any bearing on the solution, I've been using folders to organize the .cs files. So I have all of the derived classes in a folder named "Types" so to create a new instance of that object I have to type:
listA.Add(new Types.TypeA());
Upvotes: 0
Views: 278
Reputation: 447
Well, you could make a factory to class to create the object you want based on the class type passed in and use it like this:
public void AddToList(BaseType itemToAdd)
{
listA.Add(ItemFactory.Create(itemToAdd.objectName));
}
But of course, this just pushes the question down a level (but still improves the readability of the AddToList code).
To do what you're really asking requires, I think, either doing what you have already suggested: if-else chains (or a switch perhaps) to create an instance of the correct type; or using reflection to new up an instance of a dynamically chosen class.
As simple example:
BaseType Create(BaseType source)
{
var constructor = source.GetType().GetConstructor(new Type[0]);
return constructor.Invoke(new object[0]) as BaseType;
}
Upvotes: 0
Reputation: 45135
Why is your AddToList creating new objects instead of adding the itemToAdd? In other words:
public void AddToList(BaseType itemToAdd)
{
listA.Add(itemToAdd);
}
Also, there is no need to have a string for the type of object. You can get the type of any object by using:
myObj.GetType();
And you can compare the type of an object using typeof
:
if (myObj.GetType() == typeof(TypeA))
If you really, really must create new objects of the same type as itemToAdd
, then you can use Activator.CreateInstance
to avoid all those type checks:
listA.Add((BaseType)Activator.CreateInstance(itemToAdd.GetType());
But I suspect that isn't what you want to do anyway.
Upvotes: 1
Reputation: 31194
well, the first thing I see is that you're instantiating your items, and not just passing the item in
are you trying to do the following?
public void AddToList(BaseType itemToAdd)
{
listA.Add(itemToAdd);
}
the reason
public void AddToList(BaseType itemToAdd)
{
listA.Add( new itemToAdd());
}
doesn't work is because itemToAdd
is not a type, it's a variable of the type BaseType
. you can't use the new
keyword on it. it just doesn't make sense.
if you're trying to copy the item, you can do something like the following.
public void AddToList(BaseType itemToAdd)
{
listA.Add(itemToAdd.Copy());
}
You will have to write your own copy method for this part to work.
Upvotes: 2