Проблема здесь в том, что, хотя Collectable_Money
является подклассом Collectable
, это не делает SpawnPointParentDefinedCollectableParent<Collectable_Money>
подклассом CollectableParent<Collectable>
.
Возможно, это можно исправить с помощью универсальных интерфейсов.Если мы изменим CollectableParent<T>
на интерфейс и определим его как ковариант в T
через модификатор out
.(Вы не предоставили определение для CollectableRelatedMonoBehaviour
, но его также необходимо преобразовать в интерфейс):
public interface ICollectableParent<out T> : ICollectableRelatedMonoBehaviour where T : Collectable
Если затем определить список как:
public static List<ICollectableParent<Collectable>> collectableParentsList;
Затем вы можете успешно добавить к нему элементы типа SpawnPointParentDefinedCollectableParent<Collectable_Money>
.
Критическая часть здесь заключается в том, что интерфейс ICollectableParent<T>
ковариантен в T
.Это позволяет передать экземпляр, который реализует ICollectableParent<Collectable_Money>
, где ожидается ICollectableParent<Collectable>
.
Определение интерфейса как ковариантного в T
действительно вводит некоторые ограничения, конкретно (и как подразумевается в * 1031)* модификатор * используется для указания ковариации), тип T
должен использоваться только как возвращаемое значение в методах интерфейса.Например:
public interface ICollectableParent<out T> : ICollectableRelatedMonoBehaviour where T : Collectable
{
// This is allowed - T is used as a return type
T GetChild();
// This is *not* allowed - T is used as a parameter
void SetChild(T child);
}
Подробнее о ковариации и ее обратной (контравариантности) вы можете прочитать здесь: Разница между ковариацией и контрастностью