2016-06-26 3 views
3

나는 다음과 같은 몇 가지 검사를 할 필요가 있습니다클래스가 C#에서 변수로 주어진 유형의 인스턴스인지 여부를 확인하는 방법은 무엇입니까?

if(thisInstance is ThatClass || thisInstance is ThatOtherClass) 

실제로 이들의 많이 할 필요하지 않습니다, 그래서 위처럼 나는 간단하게 쓸 수 있지만, 내가 좋겠 여전히 더 깔끔한 방식으로 이것을 선호합니다. 다음과 같이하십시오 :

Type[] arrayOfClasses = new Type[] { typeof(ThatClass), typeof(ThatOtherClass))} 
if(isOfAnyType(thisInstance, arrayOfClasses)) 

그러나 나는 그것을 작동시키지 못합니다. 어떤 이유로

thisInstance.GetType() 

typeof(ThatClass) 

의 문자열 표현은
thisInstance.GetType().IsInstanceOfType(type) 

여전히 항상 false가 발생합니다 같은 것입니다하더라도.

차이점이있는 경우이 프로젝트는 Unity 프로젝트이므로 비슷한 항목 (예 : thisInstance.GetType(). GetType())에 대해 추가 GetType()을 호출하면 결과는 항상 System.MonoType이고, 이 경우 IsInstanceOfType은 항상 true를 반환하지만 물론 유용하지 않습니다.

비교가 실패한 이유나 어떻게 작동 시키는가? 아니면 그냥 포기하고 필요할 때마다 "ThisInstance is ThatClass"를 사용하면됩니까?

+1

원본 코드를 어떤 식 으로든 "깔끔하지 않은"것으로 간주하지 않습니다. 그것은 매우 직설적 인 것처럼 보입니다. 리플렉션을 사용하는 이유는 언어 연산자를 사용할 수있을 때입니다. 더 나은 질문은 "코드를 재구성하여" "수표"가 불필요 할 수 있습니까? "입니다. –

+0

글쎄, 그 두 클래스와 함께, 그것은 특히 깔끔하지는 않지만, 덜 쉽게 구성 할 수 있고, 더 많은 클래스를 사용하면 내 견해에서 약간 깔끔하게 보일 것입니다. – Jeffed

+0

물론, 그렇지만 질문은 다음과 같습니다. 어떤 유형의 런타임 검사를 많이해야하는 이유는 무엇입니까? 런타임 검사로 인해 발생하는 비효율적 인 코드를 작성하려고 시도하지 말고 대신 완전히 제거하십시오. –

답변

1

당신은 isSubclass를 사용할 수 있습니다

thisInstance.GetType().IsSubclassOf(typeof(ThatClass)) 
+1

제안 해 주셔서 감사합니다. 클래스가 매우 동일한 유형 인 경우에도 작동하지 않습니다. – Jeffed

1

는이 방법을 사용할 수있는 작업 원하는 방법을 얻으려면 : 당신이 Linq에를 사용할 수없는 경우

public static bool IsOfAnyType(object obj, Type[] types) 
{ 
    return types.Any(type => type.IsInstanceOfType(obj)); 
} 

이 같은 방법을 쓸 수 있습니다 :

:

public static bool IsOfAnyType(object obj, Type[] types) 
{ 
    foreach (var type in types) 
    { 
     if (type.IsInstanceOfType(obj)) 
      return true; 
    } 
    return false; 
} 

테스트하려면이 코드를 사용

Type[] typesToCheck = { typeof(ThatClass), typeof(ThatOtherClass) }; 

ThatClass input1 = new ThatClass(); 
ThatOtherClass input2 = new ThatOtherClass(); 

if (IsOfAnyType(input1, typesToCheck)) 
    Console.WriteLine("Hello world from " + input1.GetType()); 
if (IsOfAnyType(input2, typesToCheck)) 
    Console.WriteLine("Hello world from " + input2.GetType()); 
+3

'obj.GetType() == type'은'is'와 같은 행동을하지 않습니다.'type.IsAssignableFrom (obj.GetType())'을 사용해야합니다. –

+0

@ScottChamberlain 큰 제안, 제 대답에 추가했습니다. . 감사! –

+1

쿨, 고마워! Linq 구현은 매우 컴팩트합니다. 이전에 일부 통합 작업에 사용 했었지만 좀 더 공통적으로 사용하기 시작해야합니다. 내 생각에 "IsInstanceOfType"이 실제로하는 것보다 다소 직관적이지 않은 것은 무엇입니까? 나는 "고양이는 유형 동물의 예"라고 생각 했겠지만, "동물은 고양이의 사례"라고 거짓말을 할 것입니다. 이것이 나의 예에서 제가 시작 지점에서 그 반대의 경우가 있었던 이유입니다. 하지만 분명히 문서에 따르면 그것은 "현재 유형이 상속 계층 구조에있는 한"사실입니다, 그래서 당신의 제안은 작동합니다! – Jeffed

3

다음과 같이 사용할 수 있습니다. 메서드는 일반 객체가 배열 내의 유형 중 하나인지 여부를 확인하고 bool을 반환합니다.

public static bool IsOfAnyType<T>(T obj, Type[] types) 
    { 
     bool isOfAnyType = false; 

     for (int i = 0; i < classes.Length; i++) 
     { 
      if (types[i].IsAssignableFrom (obj.GetType())) 
      { 
       isOfAnyType = true; 
       break; 
      } 
     } 
     return isOfAnyType; 
     }  
+0

제네릭이 필요한 이유는 무엇입니까? 모든 것은 이미 '대상'에서 파생 된 것입니다. generics를 사용하는 것은 불필요한 오버 헤드가 많은 것처럼 보입니다. –

+0

@MattRowland - 나는 그 반대라고 주장 할 것입니다. 'object object'를 사용하면 내재 된 boxing과 unboxing이 일어날 것입니다. generics를 사용하는 동안 object는 type T로 유지됩니다. 실제로는 객체를 사용하든 사용하지 않든 동일한 기계 코드로 변환 할 것입니다. – pijemcolu

+0

고마워요! 제네릭의 유무에 관계없이 IsAssignableFrom이 작동하는 것 같습니다! 기이 한 일은 내가 이미 그것을 테스트했다고 생각했기 때문에 잘못된 방향으로 생각한 것 같은데 아마도 잘못된 곳에서 테스트 할 두 가지 유형이있을 것입니다. 그래서 어떤 경우에도 문제가 해결되었습니다! – Jeffed