2011-02-11 3 views
22

제목에서 알 수 있듯이 리플렉션을 사용하여 클래스 정의가 내부 클래스로 정의되어 있는지 확인하는 방법은 무엇입니까? "typeof (...)"는 아래에 표시된 특정 속성을 반환하지만 클래스가 내부로 정의되었는지 여부는 반환하지 않습니다. Google에서 찾았지만 리플렉션을 사용하여 내부 또는 보호 된 메소드를 실행하는 것에 관한 기사가 많이있었습니다. 이 경우 관심있는 메소드가 아니라 클래스 정의입니다.리플렉션을 사용하여 클래스가 내부 클래스인지 확인하는 방법은 무엇입니까?

var type = typeof(Customer); 
Assert.IsTrue(type.IsClass); 
Assert.That(type.IsAbstract, Is.EqualTo(isAbstract)); 
Assert.That(type.IsPublic, Is.EqualTo(isPublic)); 
Assert.That(type.IsPublic, Is.EqualTo(isPublic)); 
Assert.That(type.IsSealed, Is.EqualTo(isSealed)); 
Assert.That(type.IsSerializable, Is.EqualTo(isSerializable)); 

답변

26

이것은 고전적인 문제입니다. MSDN에서 :

는 C# 키워드 protectedinternal은 IL에서 의미가 없으며 리플렉션 API를 사용하지 않을 수 있습니다. IL에서 해당 용어는 FamilyAssembly입니다. Reflection을 사용하여 internal 메서드를 식별하려면 IsAssembly 속성을 사용합니다. protected internal 방법을 확인하려면 IsFamilyOrAssembly을 사용하십시오. 이 internal, protected 또는 protected internal 경우

반영 Type 검사에 길을 노출하지 않습니다.

+0

내가 MSDN 설명서가 정확한지 모르겠지만, 아마도 내가 틀렸다 : 여기 –

+0

또한,'Nested '는'class A {class B {}}'로 읽 힙니다. 여기서'B '는'A' 내에 중첩됩니다. 문서가 명시 적으로 언급 한 속성 인'IsAssembly','IsFamily'는'Type' 객체에서 공개적으로 사용할 수 없습니다. –

+0

하나의 작은 수정 : C#'protected internal'은 CLR'FamorAssem'에 해당합니다 (즉, 동일한 어셈블리 또는 파생 된 유형에있는 모든 것으로 볼 수 있음). 'FamANDAssem'에는 상응하는 C#이 없습니다 (내 꿈 제외). – zinglon

6

IsVisible 방법으로 원하는 값을 얻을 수 있습니까?

+0

IsVisible은 확실히 인터페이스의 내부 가시성을 결정하는 효과적인 방법입니다. –

0

어, 잘 모르겠지만 예.

Public Function PublicFriendOrPrivate(t As Type) As String 
    If t.IsPublic Then 
     Return "Public" 
    Else 
     If t.IsNotPublic AndAlso t.IsNested Then 
      Return "Private" 
     Else 
      Return "Friend" 
     End If 
    End If 
End Function 

'참고'친구 '는 C#의'내부 '와 같습니다.

bool isPublic(Type t) { 
    return 
     t.IsVisible 
     && t.IsPublic 
     && !t.IsNotPublic 
     && !t.IsNested 
     && !t.IsNestedPublic 
     && !t.IsNestedFamily 
     && !t.IsNestedPrivate 
     && !t.IsNestedAssembly 
     && !t.IsNestedFamORAssem 
     && !t.IsNestedFamANDAssem; 
} 

bool isInternal(Type t) { 
    return 
     !t.IsVisible 
     && !t.IsPublic 
     && t.IsNotPublic 
     && !t.IsNested 
     && !t.IsNestedPublic 
     && !t.IsNestedFamily 
     && !t.IsNestedPrivate 
     && !t.IsNestedAssembly 
     && !t.IsNestedFamORAssem 
     && !t.IsNestedFamANDAssem; 
} 

// only nested types can be declared "protected" 
bool isProtected(Type t) { 
    return 
     !t.IsVisible 
     && !t.IsPublic 
     && !t.IsNotPublic 
     && t.IsNested 
     && !t.IsNestedPublic 
     && t.IsNestedFamily 
     && !t.IsNestedPrivate 
     && !t.IsNestedAssembly 
     && !t.IsNestedFamORAssem 
     && !t.IsNestedFamANDAssem; 
} 

// only nested types can be declared "private" 
bool isPrivate(Type t) { 
    return 
     !t.IsVisible 
     && !t.IsPublic 
     && !t.IsNotPublic 
     && t.IsNested 
     && !t.IsNestedPublic 
     && !t.IsNestedFamily 
     && t.IsNestedPrivate 
     && !t.IsNestedAssembly 
     && !t.IsNestedFamORAssem 
     && !t.IsNestedFamANDAssem; 
} 
0

는 유형 (아마 잔인한 구현)의 정확한 가시성을 제공하기 위해 보장 몇 가지 기능입니다. 예를 들어`Tuple <> '은`내부 인터페이스 ITuple`을 구현합니다. 이 인터페이스의`Type`은 앞서 언급 한 플래그에 대해`false`를가집니다. 내 자신의 내부 클래스에 대한 테스트는 동일하게 작동합니다.
관련 문제