[英]Why does this generic cast fail
I have the following code: 我有以下代码:
kAIDataPort<T> lOtherEndCast = ( kAIDataPort<T>)lOtherEnd;
Which raises the following exception: 这引发了以下异常:
[A]kAI.Core.kAIDataPort`1[UnityEngine.GameObject] cannot be cast to
[B]kAI.Core.kAIDataPort`1[UnityEngine.GameObject]. Type A originates from 'kAICore...
(Exception shrunk for readability, but there is no difference between A and B. (异常缩小以便于阅读,但A和B之间没有区别。
All the other questions on generic casting seem to relate to lists and inherited types, but here we just have an object of a certain type and not being able to cast it to precisely that type. 关于通用转换的所有其他问题似乎与列表和继承类型有关,但是在这里我们只有一个特定类型的对象,而不能将它强制转换为该类型。
Not looking for a work around, I am using a non-generic base class with a non-typed method to do what I need to do, I just want to understand why this raises an exception. 不是在寻找一种解决方法,我使用非泛型基类和非类型化方法来做我需要做的事情,我只想了解为什么会引发异常。
This is in .NET 3.5 (since using Unity which still doesn't support .NET 4...) 这是在.NET 3.5中(因为使用Unity仍然不支持.NET 4 ...)
Full exception: 完全例外:
[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'.
Update: 更新:
The problem was loading the Unity DLL twice, but it was loading the same DLL (but never unloading). 问题是加载Unity DLL两次,但它加载了相同的DLL(但从未卸载)。 The code for this is:
这个代码是:
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;
The path was the same both times, so why would the case get confused about which dll to load from? 两次都是相同的路径,那么为什么要加载哪个dll会让人感到困惑呢?
Further, loading the DLL twice this way and examining the following things just before the exception I get: 此外,以这种方式加载DLL两次并在我得到的异常之前检查以下内容:
this.GetType().Equals(lOtherEnd.GetType()) false
but on the generic argument: 但在通用论点上:
typeof(T).Equals(lOtherEnd.GetType().GenericTypeArguments[0]) true
It's a generic type - the cast checks four types: T1<T2>
versus T3<T4>
. 它是一种通用类型 - 演员表检查四种类型:
T1<T2>
与T3<T4>
。
So, the collision can be either T1<G>
vs T2<G>
OR it can be T<G1>
vs T<G2>
. 因此,碰撞可以是
T1<G>
对T2<G>
或者它可以是T<G1>
对比T<G2>
。
The debug messages only printed information about 'T' and indeed it seems the same. 调试消息只打印有关'T'的信息,实际上它看起来是一样的。 So, check the Gs.
所以,检查Gs。
EDIT: 编辑:
Now I would not guess you'd do that.
现在我猜你不会这样做。
You were precisely generating multiple images of the same assembly.
您正在精确生成同一组件的多个图像。
All types created from them would always be different.
从它们创建的所有类型总是不同的。
An assembly that is loaded FROM BYTES is never 'equal' to any other assembly.
从FROM BYTES加载的程序集永远不会与任何其他程序集“相等”。
It is always loaded with new handle and never "coerced/collapsed" with any already loaded assembly.
它总是装有新的手柄,并且永远不会被任何已加载的组件“强制/折叠”。
It is always described as having
null
codebase/location and treated similarily to "dynamic assemblies", created on-the-fly.
它总是被描述为具有
( I tried to find a reference for that and I cannot. I'm still quite sure about it, but I'm striking it just to warn you that it may not be true. Here's a starter for reading about assembly loading contexts: What are 3 kinds of Binding Contexts for? ) null
代码库/位置,并且与在动态创建的“动态程序集”类似地对待。
(我试图找到一个参考,我不能。我仍然很确定它,但我只是为了警告你可能不是真的。这是一个关于装配加载环境的读物: 什么是3种绑定上下文? )
Why do you load it from raw bytes? 为什么要从原始字节加载它? Load it from FILE/PATH.
从FILE / PATH加载它。 Then it will get its codebase/location set properly and multiple loads will results in only one handle in memory.
然后它将正确设置其代码库/位置,并且多个加载将导致内存中只有一个句柄。
It seems you're casting a type T1
from assembly A1
to T1
in assembly A2
. 看来你在程序集
A2
从程序集A1
到T1
进行了类型T1
转换。 Indeed both are not same. 确实两者都不一样。 So it fails.
所以它失败了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.