VS2010 / .Net 4新的强制转换异常

时间:2010-05-25 11:53:10

标签: c# visual-studio-2010 .net-4.0

[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'   'Namespace.ISomeClass'。

我怀疑它可能与额外的DotNet安全性有关(特别是显式加载程序集,因为这是我的应用程序所做的事情。)

我怀疑这是因为我必须在配置文件中添加设置:

<runtime>
    <loadFromRemoteSources enabled="true" />
</runtime>

..但我不确定这是否相关。

更新

我看到(来自评论)我的基本代码本身不能重现问题。我想这并不奇怪。确定大型3层CQS系统的哪一部分与此问题相关将是棘手的。

一个问题可能是涉及多个程序集。我的静态类实际上是一个工厂提供者,'SomeClass'是一个类工厂(相关的工厂是通过显式汇编/类型加载在应用程序中'注册' - 见下文)。

Upfront我使用反射'注册'所有工厂(即实现特定接口的类),并且我在应用程序启动时通过识别相关程序集,加载它们并使用(实质上)将它们添加到缓存来执行此操作:

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);
}

然后我使用这个缓存来执行各种反射操作,包括“注册”工厂,这涉及循环遍历所有加载(缓存)类型并找到实现(基本)Factory接口的那些。

我曾经历过一个类似的问题(.Net 3.5,所以不完全相同),其体系结构涉及在服务器上动态创建类,并将这些类的已编译二进制文件流式传输到客户端应用程序。当尝试从远程调用反序列化客户端上的动态类的实例时出现问题:异常表示类型不知道,即使源和目标类型完全相同(包括命名空间)。基本上,类的交叉边界版本不被认为是相同的。我通过拦截反序列化过程并在本地程序集的上下文中显式定义deseriazation类类型来解决这个问题。

这种经验让我觉得这些类型被认为是不匹配的,因为(某种程度上)实际的SomeClass对象的接口,并且传递给Generic方法的接口不被认为是相同的类型。

所以(可能)我对那些更了解C#/ DotNet的问题是:类加载是如何工作的,我的应用程序认为有两种版本/类型的接口类型以及如何解决这个问题(请记住它是一个DotNet 3.5 vs 4问题,因为它在升级之前有效)?

[哇......任何来到这里的人都很耐心..谢谢]

2 个答案:

答案 0 :(得分:0)

我会说是的,它可以通过程序集的运行时加载或升级转换来实现,我在新项目中使用此代码并且没有任何问题。您能提供更多代码来复制错误吗?

答案 1 :(得分:0)

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

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

<hostingEnvironment shadowCopyBinAssemblies="false" />