Type.IsSubclassOf的行为与预期不符

时间:2009-07-16 19:08:25

标签: c# .net-3.5 assemblies appdomain

我有一个应用程序,它加载程序集并查找类型,这些类型是应用程序引用的另一个程序集A1中定义的类C1的子类。我在A1中定义了一个类型T,它是C1的子类,但是当我使用Assembly.Load(...)加载A1时,然后在T的实例上调用t.IsSubclassOf(typeof(C1))得到false。我注意到当前appdomain中有2个程序集A1的实例,如果我从其中一个实例中获取C1类型而不是两个实例,则t.IsSubclassOf(C1)可以工作。我不太明白这种行为,任何人都可以解释一下吗?此外,我如何修复我的应用程序,以便无论是加载A1还是其他程序集来查找C1的子类型?

3 个答案:

答案 0 :(得分:5)

为了使CLR唯一地标识类型,它在类型标识符中包含程序集信息。您的问题是CLR将A1的两个实例分类为不同的程序集,因此您正在有效地执行:

A1::T1.IsSubClassOf(A1Copy::C1)  // No relationship between A1 and A1Copy

...而不是:

A1::T1.IsSubClassOf(A1::C1)

程序集由其名称,版本,区域性和公钥唯一标识。请检查app-domain中两个程序集实例的这些值(通过Assembly.GetName());我怀疑其中一个属性不匹配,导致CLR加载违规组件。

答案 1 :(得分:2)

是的,我刚用这个构建了两个项目,我在一个项目中定义了父类和子类:

namespace ClassLibrary1
{
    public class Parent
    {
        public string name;
    }

    public class Child : Parent
    {
    }
}

然后尝试加载信息:

 {
        Type parent = typeof(Parent);
        Type c1 = typeof(Child);
        bool isChild1  = (c1.IsSubclassOf(parent).ToString());

        Assembly a = Assembly.Load(File.ReadAllBytes("ClassLibrary1.dll"));
        Type c2 = a.GetType(c1.FullName);
        bool isChild2 = (c2.IsSubclassOf(parent).ToString());
    }
我得到了 isChild1为true且isChild2为false。

Suzanne Cook在加载上下文时查看此链接提供了更多信息:

http://blogs.msdn.com/suzcook/archive/2003/06/13/57180.aspx

答案 2 :(得分:0)

您正在将程序集加载到(使用Assembly.Load())的AppDomain可能会导致问题。

不使用Assembly.Load(),而是使用AppDomain.CurrentDomain.Load()。这将确保将程序集加载到CurrentDomain中,您可以在其中实际使用它。

查看此文章了解更多信息:

http://blogs.microsoft.co.il/blogs/sasha/archive/2007/03/06/Assembly-Load-Contexts-Subtleties.aspx