Reputation: 977
Supposing I have the following classes:
class Master {
int x;
int y;
public int X { get { return x; } set { x = value; } }
public int Y { get { return y; } set { y = value; } }
}
class Sub1:Master {
int z;
public int Z { get { return z; } set { z = value; } }
}
class Sub2:Master {
int w;
public int W { get { return w; } set { w = value; } }
}
class Sub3:Master {
int t;
public int T { get { return t; } set { t = value; } }
}
Then I have defined three different arrays, one for each Sub*
type:
List<Sub1> array1;
List<Sub2> array2;
List<Sub3> array3;
And finally I need a way to access all instances in a unified way. The idea was to use a new array List<T>[] array4 = new[] {array1, array2, array3};
and use an int
as index, so I don't have to write three times the common operations for properties X
and Y
.
However, I can't do it in this way because the three arrays have different type. What can I use?
Upvotes: 0
Views: 221
Reputation: 15762
You can actually make this work by using the fact that IEnumerable<T>
is declared as IEnumerable<out T>
, and that Enumerable.ElementAt<T>
is optimized for the runtime type of the IEnumerable<T>
implementing IList<T>
. That lets you do this:
var x = new IEnumerable<Master>[] {array1, array2, array3};
x[0].ElementAt(4);
While still getting constant-time access to the individual elements of the lists. It feels a little clunky, but should still work.
If it fits the work being done, a better option in my opinion would be to create a generic method, and call the generic method on each of your lists:
private void MainMethod()
{
List<Sub1> array1 = new List<Sub1>();
List<Sub2> array2 = new List<Sub2>();
List<Sub3> array3 = new List<Sub3>();
DoOperation(array1);
DoOperation(array2);
DoOperation(array3);
}
private void DoOperation<T>(List<T> list) where T: Master
{
// do work here
list[0].X = 0;
}
Upvotes: 0
Reputation: 57658
They share a base type so you can create a List<Master>
to hold instances of all three types.
Ultimately, all objects share the same base type object
so it always possible to have a List<object>
, but in this case they share a base type higher in the hierarchy so you can use Master
.
To create a list for all the instances you can do something like this:
var all = new List<Master>(array1.Count + array2.Count + array3.Count);
all.AddRange(array1);
all.AddRange(array2);
all.AddRange(array3);
First you create a new list and since you already know what the expected capacity should be you use the constructor overload that accepts an int capacity
. This way the list does not have to be resized when you add the other collections, which leads to more efficient code.
As a side note and I know this is probably only sample code but nonetheless you should name your variables according to what they represent, so naming something like array*
should be reserved for when they really represent arrays.
Upvotes: 1
Reputation: 4030
List implements the non-generic interfaces ICollection
, IEnumerable
and IList
, so you can create a new array of IList[] array4 = { array1, array2, array3 };
Or, while adding elements at your Lists you could add them (also) to another list of type Master, like this
List<Sub1> array1 = new List<Sub1>();
List<Sub2> array2 = new List<Sub2>();
List<Sub3> array3 = new List<Sub3>();
List<Master> array4 = new List<Master>();
...
public void AddSub1(Sub1 sub)
{
array1.Add(sub);
array4.Add(sub);
}
public void AddSub2(Sub2 sub)
{
array2.Add(sub);
array4.Add(sub);
}
public void AddSub3(Sub3 sub)
{
array3.Add(sub);
array4.Add(sub);
}
This way, you can iterate over all elements of array4:
foreach(Master master in array4)
{
master.DoSomething();
}
Upvotes: 0