Unity中GetGenericArguments返回值与常规.NET环境不一致问题
问题原因
这个行为差异本质是不同运行时对非泛型的数组类型调用GetGenericArguments()的反射实现逻辑不一致,核心细节如下:
- 你代码里调用
GetGenericArguments()的目标是Dictionary<byte, object>[]数组类型,这个类型本身不属于泛型类型(IsGenericType属性返回false)。按照.NET官方接口定义,对非泛型类型调用GetGenericArguments()本就应该返回空数组,你在.NET控制台、在线编译器里拿到2个泛型参数属于运行时的兼容扩展行为,不是接口标准约定。 - Unity端返回空数组的原因和你使用的脚本后端有关:
- 如果使用旧版Mono后端(Unity 2019及以前默认的.NET 3.5兼容 runtime),这个版本是Unity深度定制的老旧Mono分支,严格遵循接口定义,对所有非泛型类型(包括数组)调用
GetGenericArguments()直接返回空数组。 - 如果使用IL2CPP后端,IL2CPP的反射实现没有做数组类型的泛型参数透传,同样会返回空数组。
- 如果使用旧版Mono后端(Unity 2019及以前默认的.NET 3.5兼容 runtime),这个版本是Unity深度定制的老旧Mono分支,严格遵循接口定义,对所有非泛型类型(包括数组)调用
- 标准.NET环境(.NET Core/.NET 5+、新版官方Mono)的反射实现加了兼容逻辑:当调用
GetGenericArguments()的类型是数组、引用、指针这类包装类型时,会自动解析内部被包装的元素/目标类型,如果内部类型是构造泛型类型,就返回它的泛型参数,所以你能拿到Byte和Object两个结果。
解决方案
不要直接对数组类型调用GetGenericArguments(),先做类型判断再取泛型参数,兼容所有运行时的写法如下:
Dictionary<byte, object>[] array = new Dictionary<byte, object>[] { new Dictionary<byte, object>() { { 0, "0" }, {1, "1"} }, new Dictionary<byte, object>() { { 0, "00" }, {1, "11"} } }; Type targetType = array.GetType(); // 先处理数组类型,取元素类型 if (targetType.IsArray) { targetType = targetType.GetElementType(); } Type[] types = targetType.IsGenericType ? targetType.GetGenericArguments() : Type.EmptyTypes;
你遇到的Photon库运行异常,就是因为老版本Photon的反射逻辑没有加数组类型判断,直接对数组类型调用了GetGenericArguments()。要么升级到适配Unity运行时的Photon新版本,要么自行修改库内对应的反射代码,加上上述数组判断逻辑即可修复。
内容的提问来源于stack exchange,提问作者Вадим Ципф
相关产品推荐
相关产品推荐

