2014-11-08 1 views
0

나는 다음과 같은 클래스가 :리플렉션을 사용하여 VB.Net에서 중첩 클래스를 찾는 방법은 무엇입니까?

Public Class F 
    Public Class A 
     Public Class C 

     End Class 
    End Class 

    Public Class B 

    End Class 
End Class 

그리고 나는 기본적으로 내가이 & B 유형을 반환하는 기능을 기대하고있어 클래스 F.의 내장 클래스를 반환하는 기능을 쓰고 있어요 ...

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 

이 함수를 실행하면 항상 아무 것도 반환하지 않습니다. 조건 "If Item.IsSubclassOf (baseType)"은 항상 거짓입니다.

누구든지이 코드에 무엇이 누락 되었습니까?

+2

A, C 및 B는 "하위 클래스"가 아니며 A 또는 다른 어떤 것을 상속하지 않습니다 (적어도 코드가 보여주는 한). 내부 클래스 또는 중첩 클래스입니다. – Plutonix

+0

그들은 당신이 찾고자하는 수업입니까, 아니면 다른 모임을 통해 배신하고 있습니까? – Plutonix

+0

예 Plutonix, 오해를 불러 일으킨 죄송합니다. 실제로 내부 수업입니다. 이 내부 수업 만 반환하는 방법을 알고 있습니까? –

답변

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 

출력은 다음과 같습니다 F.에서

ConsoleApplication1.A 
ConsoleApplication1.B 
ConsoleApplication1.C 

A와 B 상속 C는 A로부터 상속 때문에, 그것은 또한 F.

의 서브 클래스
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 다음 루프 동안 할 일을 제거 찾을하지 않으려면 .

0

나는 당신의 출발점이 무엇인지 모르므로 추측하고 있습니다.

Public [MustInherit] Class FooBar 
    ... 
End Class 

Public Class Foo : Inherits FooBar 
    ... 
End Class 

속성 및 방법 FooBar에 정의 무시 또는 축소 그림자가 될 수 있습니다 Foo에 의해 상속됩니다 SubClassing (원래 게시물은) 일부 부모 클래스에서 상속 하나 개의 클래스를 의미합니다. 그러나 그것은 당신이 가진 것이 아닙니다. 클래스 AB은 단순히 F의 중첩 클래스이고 CF.B 내에 중첩됩니다.

이 코드에서 인스턴스로 표시되는 baseType를 사용하여 쉽게 찾을 수 있습니다 :

Dim baseType = TBaseType.GetType 

For Each Item In baseType.GetNestedTypes 
    Console.WriteLine(Item.FullName) 
Next 

가 아니라 예를보다 유형에서 중첩 된 유형을 찾을 시작점으로 Dim baseType = GetType(FooBar)을 사용합니다. 후일에 대해 조금이라도 알고 있다면 BindingFlags을 지정하여보다 구체적으로 알 수 있습니다.예를 들어 개인 만 중첩 된 유형을 포함한다 :

For Each Item In baseType.GetNestedTypes(BindingFlags.NonPublic) 
    ... 

를하지만 루프 할 필요는 없다 :

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

나는 당신이 있기 때문에 코드는 어셈블리의 모든 유형을 통해가는 이유는 확실하지 않다 시작 기본 유형/실제 외부 유형. 그럴만한 이유가있는 경우 한스의 방법을 사용하십시오.

관련 문제