我有以下代码:
kAIDataPort<T> lOtherEndCast = ( kAIDataPort<T>)lOtherEnd;
引发以下异常:
[A]kAI.Core.kAIDataPort`1[UnityEngine.GameObject] cannot be cast to
[B]kAI.Core.kAIDataPort`1[UnityEngine.GameObject]. Type A originates from 'kAICore...
(为了可读性而缩小了异常,但 A 和 B 之间没有区别。
关于泛型转换的所有其他问题似乎都与列表和继承类型有关,但在这里我们只有一个特定类型的对象,无法将其准确转换为该类型。
不是在寻找解决方法,我正在使用非泛型基类和非类型化方法来完成我需要做的事情,我只是想了解为什么会引发异常。
这是在 .NET 3.5 中(因为使用仍然不支持 .NET 4 的 Unity...)
完全异常:
[A]kAI.Core.kAIDataPort`1[UnityEngine.GameObject] cannot be cast to
[B]kAI.Core.kAIDataPort`1[UnityEngine.GameObject].
Type A originates from 'kAICore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'E:\dev\C#\kAI\kAI-Editor\bin\Debug\kAICore.dll'.
Type B originates from 'kAICore, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'Default' at location 'E:\dev\C#\kAI\kAI-Editor\bin\Debug\kAICore.dll'.
更新:
问题是两次加载 Unity DLL,但它加载的是同一个 DLL(但从未卸载)。代码是:
FileStream lDLLStream = lDllPath.GetFile().OpenRead();
byte[] lDLLArray = new byte[lDLLStream.Length];
lDLLStream.Read(lDLLArray, 0, (int)lDLLStream.Length);
lDLLStream.Close();
Assembly lLoadedAssembly = Assembly.Load(lDLLArray);
// Force the loading of the dll
lLoadedAssembly.GetExportedTypes();
return lLoadedAssembly;
两次的路径都是一样的,那么为什么会混淆从哪个 dll 加载呢?
此外,以这种方式加载 DLL 两次,并在我得到异常之前检查以下内容:
this.GetType().Equals(lOtherEnd.GetType()) false
但是关于通用参数:
typeof(T).Equals(lOtherEnd.GetType().GenericTypeArguments[0]) true
最佳答案
它是一个通用类型——转换检查四种类型:T1<T2>
与 T3<T4>
.
因此,碰撞可以是 T1<G>
对比T2<G>
或者它可以是 T<G1>
对比T<G2>
.
调试消息只打印了关于“T”的信息,实际上看起来是一样的。所以,检查 Gs。
编辑:
现在我猜你不会那样做。您精确地生成了同一组件的多个图像。从它们创建的所有类型总是不同的。
从 BYTES 加载的程序集永远不会与任何其他程序集“相等”。它始终加载有新句柄,并且从不与任何已加载的程序集“强制/折叠”。它总是被描述为有 null
codebase/location 并类似于“动态程序集”,即时创建。它只是为了警告您这可能不是真的。这是阅读程序集加载上下文的入门指南:What are 3 kinds of Binding Contexts for? )
为什么要从原始字节加载它?从文件/路径加载它。然后它将正确设置其代码库/位置,多次加载将导致内存中只有一个句柄。
关于c# - 为什么这个通用转换失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20270056/