Unity泛型容器列表添加报错ArrayTypeMismatchException求解决方案
问题分析与解决办法
我之前在Unity 5.x版本也碰到过一模一样的问题,这本质上是Unity当时搭载的Mono运行时对泛型协变的支持存在兼容性bug——虽然你的代码在标准.NET环境下完全合法(因为IContainer<out T>声明了协变,IContainer<Cat>理应可以隐式转换为IContainer<Animal>),但Unity的Mono在处理List<T>的Add操作时,内部数组的类型检查逻辑没有正确识别这种协变转换,导致抛出ArrayTypeMismatchException。
给你几个可行的解决办法:
办法1:引入非泛型基接口
给IContainer<T>添加一个非泛型的基接口,然后让列表存储这个非泛型接口的实例:
public interface Animal { void bar(); } // 添加非泛型基接口 public interface IContainerBase { void foo(); } public interface IContainer<out T> : IContainerBase where T : Animal { } public class Cat : Animal { public void bar() {} } public class CatContainer : IContainer<Cat> { public void foo() {} } public void test () { List<IContainerBase> list = new List<IContainerBase>(); list.Add(new CatContainer()); // 正常运行 }
这种方式完全绕开了泛型协变的转换问题,兼容性最好,适合所有存在该bug的Unity版本。
办法2:强制类型转换绕开检查
如果不想修改接口结构,可以通过先转成object再强制转换的方式,绕开Mono的类型检查逻辑:
public void test () { List<IContainer<Animal>> list = new List<IContainer<Animal>>(); // 先转object再转目标类型,运行时会正确识别协变 list.Add((IContainer<Animal>)(object)new CatContainer()); }
这个办法不需要改动原有接口,适合快速修复现有代码。
办法3:升级Unity版本
Unity在2018及以后的版本中更新了Mono运行时,修复了这个泛型协变的兼容性问题。如果项目允许升级Unity,这是一劳永逸的解决方案。
内容的提问来源于stack exchange,提问作者puglic
相关产品推荐
相关产品推荐

