【问题标题】:New cast exception with VS2010/.Net 4VS2010/.Net 4 的新转换异常
【发布时间】: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


【解决方案1】:

我会说是的,它与程序集的运行时加载或升级转换有关,我在一个新项目中使用了此代码并且没有任何问题。你能提供更多代码来复制错误吗?

【讨论】:

  • 感谢您的努力 :) [显然我没有在我的真正问题代码之外尝试这个确切的代码] 我将在主帖中添加更多信息。
【解决方案2】:

“快速”(ITO 实现,而不是 ITO 找到它)解决方案是停止我的应用程序 DLL 的卷影副本。 这是通过如下修改 ASP.Net 应用程序的 Web.Config 文件来完成的:

在“配置/web.settings”部分,添加设置:

<hostingEnvironment shadowCopyBinAssemblies="false" />

【讨论】:

    猜你喜欢
    • 2016-08-05
    • 2015-08-10
    • 2011-05-22
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 2023-03-21
    • 2011-12-23
    相关资源
    最近更新 更多