为什么这个通用演员会失败

时间:2013-11-28 15:41:47

标签: c# generics

我有以下代码:

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中(因为使用Unity仍然不支持.NET 4 ...)

完全例外:

[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

2 个答案:

答案 0 :(得分:3)

这是一种通用类型 - 演员会检查四种类型:T1<T2>T3<T4>

因此,碰撞可以是T1<G>T2<G>,也可以是T<G1>T<G2>

调试消息只打印有关'T'的信息,实际上它看起来是一样的。所以,检查一下Gs。

编辑:

现在我猜你不会这样做。您正在精确生成同一组件的多个图像。从它们创建的所有类型总是不同的。

从FROM BYTES加载的程序集永远不会与任何其他程序集“相等”。它总是装有新的手柄,并且永远不会被任何已加载的组件“强制/折叠”。它总是被描述为具有null代码库/位置,并且类似于“动态组件”,即时创建。(我试图找到它的参考,我不能。我是仍然非常肯定,但我只是为了警告你这可能不是真的。这是一个关于装配加载上下文的读物:What are 3 kinds of Binding Contexts for?

为什么要从原始字节加载它?从FILE / PATH加载它。然后它将正确设置其代码库/位置,多个加载将导致内存中只有一个句柄。

答案 1 :(得分:2)

您似乎在程序集T1中将程序集A1中的T1类型转换为A2。确实两者都不一样。所以它失败了。