Storing list of generic class of derived objects

纵饮孤独 提交于 2020-01-06 01:36:50

问题


For example, how do I store a list of DataContainers that all use types that derive from the same base class.

public class Animal {}
public class Cat : Animal {}
public class Dog : Animal {}
public class DataContainer <TData> where TData : Animal {
    TData innerObject = new TData ();
    public TData GetData () {
        return innerObject;
    }
}

public class DataManager {
    static void Main () {
        DataContainer<Cat> CatData = new DataContainer<Cat> ();
        DataContainer<Dog> DogData = new DataContainer<Dog> ();
        var AnimalData = new List<DataContainer<Animal>> ();
        AnimalData.Add (CatData);
        AnimalData.Add (DogData);
        for (int i = 0; i < AnimalData.Count; i++) {
            Animal animal = AnimalData[i].GetData ();
        }
    }
}

If it's not possible with a generic class, could it be possible with Arrays?

Edit: Getting this error: ArrayTypeMismatchException: Source array type cannot be assigned to destination array type. This causes an ArrayTypeMismatchException:

public interface IDataContainer <out TData> where TData : Animal {

}
public class DataContainer <TData> : IDataContainer<TData> where TData : Animal {

}

public class Tester () {
    static void Main () {
        var AnimalData = new List<DataContainer<Animal>> ();
        var CatData = new DataContainer<Cat> ();
        AnimalData.Add (CatData as IDataContainer<Animal>); //Error
    }
}

Run in Unity 5.2


回答1:


The issue is that you need your generic class to have a covariant type parameter.

You can only do this on interfaces, so create one:

public interface IDataContainer <out TData> where TData : Animal 
{
    TData GetData ();
}

Note the use of out to mark TData as covariant. Now have your DataContainer class implement the interface, and when you hold onto a reference in the client code, make sure its an IDataContainer. Now it should let you store it as you expected.

Do note that covariant interfaces have special requirements, namely that the generic type parameter can not be used as the argument type for any of the methods (see the MSDN link for more).



来源:https://stackoverflow.com/questions/33181041/storing-list-of-generic-class-of-derived-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!