我是Unity的C#游戏开发商。我有可收集的管理系统。
CollectableManager
import { PopulateComponents } from './populate-components';
@NgModule({
declarations: [(...) PopulateComponents],
CollectableParent
public List<CollectableParent<Collectable>> collactableParentsList;
SpawnPointDefinedCollectableParent
public class CollectableParent<T> : CollectableRelatedMonoBehaviour where T : Collectable
可收集
public class SpawnPointParentDefinedCollectableParent<T> : CollectableParent<T> where T : Collectable
Collectable_Money
public abstract class Collectable : CollectableRelatedMonoBehaviour, IHasPlayableSound
CollectableParent_Money
public class Collectable_Money : Collectable
问题
当T被定义为“ Collectable_Money”时,CollectableManager中的“ collactableParentsList”不接受public class CollectableParent_Money : SpawnPointParentDefinedCollectableParent<Collectable_Money>
作为项目,它是从“ Collectable”派生的。如果我这样做SpawnPointParentDefinedCollectableParent<Collectable_Money>
,它将被接受为列表中的项目。
答案 0 :(得分:2)
这里的问题是,即使Collectable_Money
是Collectable
的子类,也不会使SpawnPointParentDefinedCollectableParent<Collectable_Money>
成为{{ 1}}。
使用通用接口可以解决此问题。如果我们将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
修饰符所暗示的那样),类型out
必须仅用于接口方法的返回值。例如:
T
您可以在此处详细了解协方差及其逆(协方差):Difference between Covariance & Contra-variance