객체가 인터페이스를 구현하는지 테스트


355

개체가 C #에서 지정된 인터페이스를 구현하는 경우 가장 간단한 테스트 방법은 무엇입니까? ( Java 에서이 질문 대한 답변 )

답변:


569
if (object is IBlah)

또는

IBlah myTest = originalObject as IBlah

if (myTest != null)

85
+1 두 번째 캐스트는 아마도 첫 번째 캐스트와 함께 나중에 캐스트해야하므로 두 개의 캐스트 ( "is"와 명시 적 캐스트)를 요구하기 때문에 더 좋습니다. 두 번째 방법을 사용하면 한 번만 캐스팅 할 수 있습니다.
Andrew Hare

51
@ 앤드류 : +1; Julian M Bucknall 의 클래식 Double-Casting AntiPattern 블로그 게시물에 대한 링크 를 다시 한 번 살펴보십시오 .
Jeroen Wiert Pluimers

1
최적화는 아마도 첫 번째 경우에 두 번 캐스팅하지 않았습니까?
BuZz

1
@Joreen, 당신이 "as"가 리턴하려고하는 널을 보유하지 않기 때문에 "as"를 사용할 수없는 구조를 가지고 작업한다면 그 링크는 한 지점을 놓치게됩니다. int?와 같은 클래스?, 항상 참조 유형이므로 인터페이스 레벨에서만 작업하는 경우에는 문제가되지 않습니다.
MikeT

46
C # 6.0 이후 :if (object is IBlah iblah) { iblah.SomeMethod(); }
Knelis

224

컴파일 타임에 인터페이스 유형을 알고 테스트중인 유형의 인스턴스가있는 경우 isor as연산자를 사용하는 것이 올바른 방법입니다. 다른 사람이 언급하지 않은 것 Type.IsAssignableFrom:

if( typeof(IMyInterface).IsAssignableFrom(someOtherType) )
{
}

나는 이것이 반환 된 배열을 보는 것보다 훨씬 깔끔하고 GetInterfaces클래스 작업도 장점 이라고 생각합니다 .


형식이 IList의 인스턴스화를 구현하는지 확인하려고합니다. "typeof (IList <>). IsAssignableFrom (someType)"을 사용하고 있지만 작동하지 않습니다.
KeyboardDrummer

3
다른 질문으로 이것을 묻는 것이 좋습니다. someType이 목록 요소의 유형 인 경우 typeof (IList <>). MakeGenericType (someType)이 필요할 수 있습니다. someType이 목록 유형 인 경우 Type.GetGenericArguments 및 Type.GetGenericTypeDefinition을 확인해야합니다.
앤드류 케난

플러그인 시스템에서 유형 검사에 이것을 사용합니다. 객체의 인스턴스가 아직없는 상황에서 사용할 수 있습니다. 그러나 내가하고있는 일에 따라이 스타일과 Robert의 스타일을 모두 사용하므로 두 가지 방식으로 투표했습니다.
James

이것은 오래된 의견이지만 @Steenreem의 질문에 대답하려면을 사용 typeof(IList).IsAssignableFrom(someType)하지 않고을 사용 하십시오 <>.
saluce

이 방법은도 변환 운영자와 협력하고 TypeConverters가 참여하는 경우
헤럴드 Coppoolse에게

22

예를 들어 :

if (obj is IMyInterface) {}

수업 :

typeof(MyClass).GetInterfaces()인터페이스 가 포함되어 있는지 확인하십시오 .


1
if (Array.IndexOf (typeof (MyClass) .GetInterfaces (), typeof (IMyInterface)))! = -1) {...}
Constantin

2
또는 : if (typeof (MyClass) .GetInterfaces (). Contains (typeof (IMyInterface))) {...}
랜스 피셔


16

@AndrewKennan의 대답에 대한 변형은 최근 런타임에 얻은 유형에 대해 최근에 사용되었습니다.

if (serviceType.IsInstanceOfType(service))
{
    // 'service' does implement the 'serviceType' type
}

7

게시물 은 좋은 답변입니다.

public interface IMyInterface {}

public class MyType : IMyInterface {}

이것은 간단한 샘플입니다.

typeof(IMyInterface).IsAssignableFrom(typeof(MyType))

또는

typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))

3

"is"연산자를 사용하여 테스트하는 것 외에도 메소드를 장식하여 전달 된 변수가 다음과 같이 특정 인터페이스를 구현하는지 확인할 수 있습니다.

public static void BubbleSort<T>(ref IList<T> unsorted_list) where T : IComparable
{
     //Some bubbly sorting
}

이것이 어떤 .Net 버전으로 구현되었는지 잘 모르겠으므로 버전에서 작동하지 않을 수 있습니다.


2
.net 2.0에 제네릭이 추가되었습니다.
Robert C. Barth

이 스레드에서 유일한 컴파일 타임 검사입니다. 감사합니다.
더스틴 말론

2

나를 위해 일한 것은 다음과 같습니다.

Assert.IsNotNull(typeof (YourClass).GetInterfaces().SingleOrDefault(i => i == typeof (ISomeInterface)));


1

최근 Andrew Kennan의 답변을 사용해 보았지만 어떤 이유로 든 작동하지 않았습니다. 대신 이것을 사용하고 작동했습니다 (참고 : 네임 스페이스를 작성해야 할 수도 있습니다).

if (typeof(someObject).GetInterface("MyNamespace.IMyInterface") != null)

2
이 경로로 이동하면 마술 문자열의 팬이 아니므로 최소한 "MyNamespace.IMyInterface"대신 typeof (IMyInterface) .Name으로 변경해야합니다. 리팩토링 증거를 보너스로 지정하는 데 도움이됩니다.
greyalien007

0

나는 사용했다

Assert.IsTrue(myObject is ImyInterface);

myObject가 내 인터페이스 ImyInterface를 구현 한 객체인지 테스트하는 단위 테스트 테스트.


-1

변수를 메소드에 전달하고 인터페이스 또는 객체인지 확실하지 않은 상황이있었습니다.

목표는 다음과 같습니다.

  1. item이 인터페이스 인 경우 인터페이스를 생성자 호출에서 매개 변수로 사용하여 해당 인터페이스를 기반으로 오브젝트를 인스턴스화하십시오.
  2. 항목이 객체 인 경우 호출의 구성자가 인터페이스를 기대하고 코드를 탱크로 만들고 싶지 않기 때문에 null을 반환합니다.

나는 이것을 다음과 같이 달성했다.

    if(!typeof(T).IsClass)
    {
       // If your constructor needs arguments...
       object[] args = new object[] { my_constructor_param };
       return (T)Activator.CreateInstance(typeof(T), args, null);
    }
    else
       return default(T);

-12

이것은 작동해야합니다 :

MyInstace.GetType().GetInterfaces();

그러나 너무 좋은 :

if (obj is IMyInterface)

또는 심지어 (아주 우아하지 않음) :

if (obj.GetType() == typeof(IMyInterface))

9
typeof (IMyInterface)와 같은지 확인하는 것은 항상 실패합니다. 공감.
Jay Bazuzi 님의

권리. 인터페이스 인스턴스가 없습니다.
Rauhotz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.