【发布时间】:2010-05-25 11:53:10
【问题描述】:
[ 2010 年 5 月 25 日更新] 我最近从VS2008升级到VS2010,同时升级到.Net 4。
我重新编译了我的现有解决方案,但遇到了以前没有的 Cast 异常。
代码的结构很简单(虽然实际实现要复杂一些)。
基本上我有:
public class SomeClass : ISomeClass
{
// Stuff
}
public static class ClassFactory
{
public static IInterface GetClassInstance<IInterface>(Type classType)
{
return (IInterface)Activator.CreateInstance(classType); // This throws a cast exception
}
}
// Call the factory with:
ISomeClass anInstance = ClassFactory.GetClassInstance<ISomeClass>(typeof(SomeClass));
忽略上述的“合理性” - 它仅提供问题的表示,而不是我正在做什么的细节(例如,构造函数参数已被删除)。
标记的行抛出异常:
无法转换类型的对象 'Namespace.SomeClass' 键入 '命名空间.ISomeClass'。
我怀疑这可能与额外的 DotNet 安全性有关(特别是显式加载程序集,因为这是我的应用程序所做的)。
我怀疑这是因为我必须将设置添加到配置文件中:
<runtime>
<loadFromRemoteSources enabled="true" />
</runtime>
.. 但我不确定这是否相关。
更新
我看到(来自 cmets)我的基本代码本身不会重现问题。我想这并不奇怪。要确定大型 3 层 CQS 系统的哪个部分与此问题相关是很棘手的。
一个问题可能是涉及多个程序集。我的静态类实际上是一个工厂提供者,而“SomeClass”是一个类工厂(与工厂通过显式程序集/类型加载在应用程序中“注册”有关 - 见下文)。
前期我使用反射来“注册”所有工厂(即实现特定接口的类),并且在应用程序启动时通过识别相关程序集、加载它们并将它们添加到缓存中来执行此操作(本质上) :
Loop over (file in files)
{
Assembly assembly = Assembly.LoadFile(file);
baseAssemblyList.Add(assembly);
}
然后我缓存这些程序集中的可用类型:
foreach (Assembly assembly in _loadedAssemblyList)
{
Type[] assemblyTypes = assembly.GetTypes();
_loadedTypesCache.AddRange(assemblyTypes);
}
然后我使用这个缓存来执行各种反射操作,包括工厂的“注册”,这涉及循环所有加载(缓存)的类型并找到实现(基本)工厂接口的那些。
我在过去遇到过类似的问题(.Net 3.5,因此不完全相同),其架构涉及在服务器上动态创建类并将这些类的编译二进制流传输到客户端应用程序.当尝试从远程调用反序列化客户端上的动态类的实例时出现问题:异常表示类类型未知,即使源类型和目标类型完全相同(包括命名空间)。基本上,该类的跨界版本不被认为是相同的。我通过拦截反序列化过程并在本地程序集的上下文中明确定义反序列化类类型来解决这个问题。
这种经历让我认为类型不匹配,因为(不知何故)实际 SomeClass 对象的接口和传递给 Generic 方法的接口不被认为是同一类型。
所以(可能)对于那些更了解 C#/DotNet 的人来说,我的问题是:类加载是如何工作的,我的应用程序认为接口类型有两个版本/类型,我该如何解决这个问题(记住它是一个 DotNet 3.5 vs 4 问题,因为它在我升级之前就可以工作)?
[呼……来的人都挺有耐心的……谢谢]
【问题讨论】:
-
检查你没有两个名为
SomeClass的类,但只有一个实现了ISomeClass... -
... 或者有两个
ISomeClass接口(在不同的程序集中)。 -
不明确。我已经用细节更新了主要问题,但我怀疑 DotNet 认为有两种名称完全相同的类型(我猜它是接口类型),不知何故是由于我显式加载程序集及其类型引起的。问题是:如何避免这种情况?
-
Riiight。奇怪的是,这个问题是间歇性的。这向我表明它可能是由位于 BIN 目录中的残留(DotNet 升级/重建前)DLL 引起的。我已删除所有此类 DLL 并运行该应用程序 - 没有错误。但是,正如我所说,这个问题是间歇性的,所以它可能只是在缓解。
-
未解决。仍然间歇性发生,这本身就很可疑。
标签: c# visual-studio-2010 .net-4.0