简体   繁体   English

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

[英]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. 从它们创建的所有类型总是不同的。

\n

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. 它总是被描述为具有 null代码库/位置,并且与在动态创建的“动态程序集”类似地对待。 ( 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? ) (我试图找到一个参考,我不能。我仍然很确定它,但我只是为了警告你可能不是真的。这是一个关于装配加载环境的读物: 什么是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从程序集A1T1进行了类型T1转换。 Indeed both are not same. 确实两者都不一样。 So it fails. 所以它失败了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在测试受约束的泛型类型时直接强制转换失败但“as”运算符成功? - Why does a direct cast fail but the “as” operator succeed when testing a constrained generic type? 为什么这个演员操作失败了 - Why does this cast-operation fail 为什么从short到int的转换失败? - Why does this cast from short to int fail? 为什么对泛型列表进行显式强制转换不起作用 - why does explicit cast for generic list not work 为什么通用测试会失败,但非通用测试却不会? - Why does a generic test fail but the non generic does not? 为什么使用ToList时此Linq Cast失败? - Why does this Linq Cast Fail when using ToList? 为什么从IEnumerable投射 <string> 列表 <string> 失败? - Why does cast from IEnumerable<string> to List<string> fail? 为什么在案例1中转换操作失败但在案例2中成功? - Why does the cast operation fail in case 1 but succeed in case 2? 为什么将具有通用参数的接口转换为约束较少的同一接口不起作用? - Why cast of the interface with generic parameter to the same interface with less constraints does not work? 转换泛型类型 - 为什么带括号“()”的直接转换会产生编译错误,但使用“as”关键字进行转换却有效? - Casting Generic Types - Why does a direct cast with parenthesis "()" give a compile-error, but casting with the "as"-keyword works?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM