如何使用反射在VB.Net中找到嵌套类?

时间:2014-11-08 01:33:30

标签: vb.net reflection

我有以下课程:

Public Class F
    Public Class A
        Public Class C

        End Class
    End Class

    Public Class B

    End Class
End Class

我正在编写一个函数来返回类F的嵌入类。基本上我期望函数返回A& B类型......

Public Function FindInternalClasses(ByVal TBaseType As Object) As List(Of Type)
    Dim baseType = TBaseType.GetType
    Dim assembly = baseType.Assembly
    Dim Output As New List(Of Type)

    For Each Item In assembly.GetTypes
        If Item.IsSubclassOf(baseType) Then
            Output.Add(Item)
        End If
    Next

    Return Output
End Function

运行此功能时,它始终不返回任何内容。 (条件“如果Item.IsSubclassOf(baseType)”始终为false。)

有人知道这段代码缺少什么吗?

3 个答案:

答案 0 :(得分:1)

它们是嵌套类型。嵌套类型与其外部类型没有任何继承关系,因此IsSubclassOf()无法工作。使它们与众不同的唯一属性是Type.DeclaringType属性,它引用它们的外部类型。所以你的代码应该是这样的:

Public Function FindNestedTypes(ByVal outerType As Type) As List(Of Type)
    Dim output As New List(Of Type)
    For Each item In outerType.Assembly.GetTypes()
        Dim declarer = item.DeclaringType
        Do While declarer IsNot Nothing
            If declarer Is outerType Then
                output.Add(item)
                Exit Do
            End If
            declarer = declarer.DeclaringType
        Loop
    Next
    Return output
End Function

样本用法:

For Each t As Type In FindNestedTypes(GetType(F))
    Console.WriteLine(t.FullName)
Next

输出:

ConsoleApplication1.F+A
ConsoleApplication1.F+B
ConsoleApplication1.F+A+C

如果您不想找到C类,请删除Do While循环。

答案 1 :(得分:0)

你快到了。你有大约95%的功能。以下应该可以解决问题。

Imports System.Reflection

Module Module1

    Sub Main()
        Dim obj As New F()

        Dim result = GetSubClasses(obj)

        For Each t As Type In result
            Console.WriteLine(t)
        Next

        Console.ReadLine()
    End Sub

    Public Function GetSubClasses(ByRef obj As Object) As List(Of Type)
        Dim baseType = obj.GetType()
        Dim output As New List(Of Type)

        For Each t As Type In Assembly.GetExecutingAssembly().GetTypes()
            If t.IsSubclassOf(obj.GetType()) Then
                output.Add(t)
            End If
        Next

        Return output
    End Function
End Module

Public Class F

End Class

Public Class A : Inherits F

End Class

Public Class B : Inherits F

End Class

Public Class C : Inherits A

End Class

以下内容的输出为:

ConsoleApplication1.A
ConsoleApplication1.B
ConsoleApplication1.C

A和B继承自F.因为C继承自A,它也被认为是F的子类。

答案 2 :(得分:0)

我不确定你的出发点是什么,所以我猜。 SubClassing(原始帖子)是指从某个父类继承的一个类:

Public [MustInherit] Class FooBar
   ...
End Class

Public Class Foo : Inherits FooBar
   ...
End Class

FooBar中定义的属性和方法由Foo继承,可以覆盖或遮蔽。但那不是你拥有的。类AB只是F的嵌套类,而C嵌套在F.B中。

使用baseType很容易找到它们,Dim baseType = TBaseType.GetType For Each Item In baseType.GetNestedTypes Console.WriteLine(Item.FullName) Next 似乎是代码中的一个实例:

Dim baseType = GetType(FooBar)

要从Type而不是实例中查找嵌套类型,请使用BindingFlags作为起点。如果你对后面的内容有所了解,可以通过指定For Each Item In baseType.GetNestedTypes(BindingFlags.NonPublic) ... 来获得更具体的信息。例如,仅包括私有的嵌套类型:

Dim Output = New List(Of Type)(TBaseType.GetType.GetNestedTypes(BindingFlags.Public))

但它不一定是一个循环:

{{1}}

我不确定为什么你的代码通过程序集中的所有类型,因为你有起始baseType / actual外部类型;如果有充分的理由,请使用Hans的方法。