I feel like interface (contra?)variance is the answer, but cannot find the right solution.
Let us have these classes:
public abstract class Fruit { }
public class Banana : Fruit { }
public class Apple : Fruit { }
public abstract class Picture { }
public class FruitPicture<T> : Picture, Contravariant<T>, Covariant<T> where T : Fruit
{
T myFruit = null;
public Type GetFruitType() { return typeof(T); }
public void AddFruit(T fruit) { this.myFruit = fruit; }
}
public interface Contravariant<in T> { void AddFruit(T model); }
public interface Covariant<out T> { Type GetFruitType(); }
My situation being:
I have a collection of Bananas and Apples already initialized, such as these two (but I can use a different one):
Fruit[] myFruits = new Fruit[2] { new Banana(), new Apple() };
I have a collection of Pictures, such as these two:
Picture[] myPictures = new Picture[2] { new FruitPicture<Banana>(), new FruitPicture<Apple>(), };
Now, I seek to do a very simple thing, but in a versatile manner, meaning I want to avoid any switches/ifs where I would have to change code each time a new fruit is found and new FruitPicture may appear in the collection => I want to .AddFruit()
from my collection to the proper type of FruitPicture. I can change pretty much any of the logic, but I want to keep the generic FruitPicture class.
Closest I got would be:
foreach(Picture curPicture in myPictures)
{
foreach (Fruit curFruit in myFruits)
{
Covariant<Fruit> fruitType = (Covariant<Fruit>)curPicture;
if (curFruit.GetType() == fruitType.GetFruitType())
{
// what now?
}
}
}
Thank you mr. Skeet (joking; sort of)