【问题标题】:Reflection and casting反射和铸造
【发布时间】:2010-10-21 03:27:17
【问题描述】:

我有以下情况,当我尝试投射时抛出异常:

  1. 我添加了项目引用并导入了项目的命名空间。
  2. Lo​​adFile 行加载构建此项目时生成的 dll。
  3. 我正在尝试访问从 dll 中装饰对象属性的属性的公共字段。
  4. 这里是异常文本:

[A]MyNamespace.PropertyMetaDataAttribute 无法转换为 [B]MyNamespace.PropertyMetaDataAttribute。类型 A 源自位置“C:\projectA\bin\debug\A.dll”的上下文“LoadFrom”中的“A,版本=12.0.0.25,Culture=neutral,PublicKeyToken=null”。类型 B 源自 'A, Version=12.0.0.25, Culture=neutral, PublicKeyToken=null' 在位置 'C:\currentProject\bin\debug\A.dll' 的上下文 'Default' 中。

代码sn-p:

using MyNamespace; // added project reference to this item

m_Assembly = Assembly.LoadFile(ConfigurationManager.AppSettings["DLL_File_Path"]);

 Type objectType = m_Assembly.GetType(string.Format("{0}.{1}", NAMESPACE_PREFIX, "MyObject"));

 // Crash happens on line below:

 Attribute attr = (Attribute) objectType.GetProperty("Name").GetCustomAttributes(false)[0];

//This is the layout of the object which has the property
 MyObject
 {
    [MyAttribute(Name="FooName")]
    Foo {get;set;}
 }

// This is the definition of the attribute
 MyAttribute :Attribute
 {
    // Want to access the value
    public string Name = string.Empty;
 }

【问题讨论】:

    标签: .net reflection


    【解决方案1】:

    好像是你的

    ConfigurationManager.AppSettings["DLL_File_Path"]
    

    指向其他位置的同一个 dll,因此 .Net 运行时会尝试加载已加载的 dll,当您尝试使用它时,类型系统会因为 2 个 dll 之间重复的类型而崩溃。 .

    根据报错,这是两个dll的位置

    • C:\currentProject\bin\debug\A.dll
    • C:\projectA\bin\debug\A.dll

    如果在解决方案上明确设​​置了引用,您可以尝试将本地复制设置为 False,这样当解决方案生成时,不要复制依赖项的结果

    【讨论】:

      【解决方案2】:

      如果您的 dll 已经在自动搜索的路径(当前目录、bin 等)中,并且因为您在该程序集中引用了某些内容而被加载,那么您的 LoadFile(您可能也想使用 LoadFrom)将加载相同的 DLL 到另一个上下文(LoadFrom-context)而不是默认。

      您应该考虑只加载一次 DLL,或者尝试首先从默认上下文中获取程序集以避免冲突,方法是查看 AppDomain.CurrentDomain.GetAssemblies()。

      如果您尝试访问不在默认上下文中的程序集,您甚至可以将 AssemblyResolve-eventhandler 附加到 AppDomain.CurrentDomain 作为后备。

      http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyresolve.aspx

      AppDomain.CurrentDomain.GetAssemblies() 将包含来自所有上下文的程序集,甚至是您使用 LoadFrom/LoadFile 加载的程序集。

      【讨论】:

        【解决方案3】:

        当您加载程序集时,您可以将类型加载到不同的上下文中。这就是为什么您不能从一种类型转换为另一种类型的原因。您可以使用 AssemblyResolve 事件(正如 jishi 建议的那样)解决此问题,或者还有一个 TypeResolve 事件,您可以在使用它时使用它来返回正确的类型,但我认为您只需要对齐程序集到正确的上下文并了解加载的时间和方式以及适合您的内容。

        这些来自 Suzanne Cook 博客的文章确实帮助我了解了不同的上下文以及事物是如何加载到其中的以及为什么。

        http://blogs.msdn.com/suzcook/archive/2003/09/19/loadfile-vs-loadfrom.aspx

        http://blogs.msdn.com/suzcook/archive/2003/05/29/57143.aspx

        此外,如果您想了解它们的加载方式和原因,您应该查看 Fusion logs 并将它们设置为转储所有信息,它会向您显示程序集的加载信息。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-08-01
          • 2015-04-06
          • 1970-01-01
          相关资源
          最近更新 更多