Probar si el objeto implementa la interfaz


Respuestas:


570
if (object is IBlah)

o

IBlah myTest = originalObject as IBlah

if (myTest != null)

85
+1 El segundo es mejor porque probablemente terminarás necesitando lanzar después con el primero, dándote dos lanzamientos ("es" y luego un lanzamiento explícito). Con el segundo enfoque solo lanzas una vez.
Andrew Hare el

51
@Andrew: +1; Una vez más, el enlace a la clásica publicación de blog Anti-Patrón de doble fundición de Julian M Bucknall .
Jeroen Wiert Pluimers

1
¿La optimización probablemente no te hará lanzar dos veces en el primer caso?
BuZz

1
@Joreen, ese enlace pierde un punto si está trabajando con una estructura que no puede usar "como" porque no contendrá un valor nulo, que es lo que el "como" intenta devolver, en ese caso debe pasar por un elemento anulable class like int ?, aunque no es un problema si solo trabajas a nivel de interfaz, ya que siempre son tipos de referencia
MikeT

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

224

Usar los operadores iso ases la forma correcta si conoce el tipo de interfaz en tiempo de compilación y tiene una instancia del tipo que está probando. Algo que nadie más parece haber mencionado es Type.IsAssignableFrom:

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

Creo que esto es mucho más ordenado que mirar a través de la matriz devuelta GetInterfacesy también tiene la ventaja de trabajar para las clases.


Estoy tratando de determinar si un tipo implementa alguna instanciación de IList. Estoy usando "typeof (IList <>). IsAssignableFrom (someType)" pero eso no funciona.
KeyboardDrummer

3
Es mejor que hagas esto en otra pregunta. Si someType es el tipo de elementos de la lista, podría necesitar typeof (IList <>). MakeGenericType (someType). Si someType es el tipo de lista, debe mirar Type.GetGenericArguments y Type.GetGenericTypeDefinition.
Andrew Kennan

Lo uso para la verificación de tipos en un sistema de complementos. Se puede utilizar en situaciones en las que todavía no existe una instancia del objeto. Pero uso tanto este estilo como el de Robert dependiendo de lo que estoy haciendo, así que voté en ambos sentidos.
James

Este es un comentario anterior, pero para responder a la pregunta de @ Steenreem, use typeof(IList).IsAssignableFrom(someType), sin el <>.
Salse

Este método incluso funciona con operadores de conversión y si los TypeConverters están involucrados
Harald Coppoolse

22

Por ejemplo:

if (obj is IMyInterface) {}

Para la clase:

Compruebe si typeof(MyClass).GetInterfaces()contiene la interfaz.


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

2
o: if (typeof (MyClass) .GetInterfaces (). Contiene (typeof (IMyInterface))) {...}
Lance Fisher el


16

Una variación de la respuesta de @ AndrewKennan que terminé usando recientemente para los tipos obtenidos en tiempo de ejecución:

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

7

Esta publicación es una buena respuesta.

public interface IMyInterface {}

public class MyType : IMyInterface {}

Esta es una muestra simple:

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

o

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

3

Además de probar con el operador "es", puede decorar sus métodos para asegurarse de que las variables que se le pasen implementen una interfaz particular, de esta manera:

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

No estoy seguro de qué versión de .Net se implementó, por lo que es posible que no funcione en su versión.


2
.net 2.0 agregó genéricos.
Robert C. Barth

Esta es la única comprobación en tiempo de compilación en este hilo, gracias.
Dustin Malone

2

Lo que funcionó para mí es:

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


1

Recientemente intenté usar la respuesta de Andrew Kennan y no me funcionó por alguna razón. Utilicé esto en su lugar y funcionó (nota: podría ser necesario escribir el espacio de nombres).

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

2
Si terminas yendo por esta ruta, no soy un fanático de las cadenas mágicas, así que como mínimo cambiaría esto para que sea typeof (IMyInterface) .Name en lugar de "MyNamespace.IMyInterface". Ayuda a nombrar la prueba de refactorización como un bono.
greyalien007

0

solía

Assert.IsTrue(myObject is ImyInterface);

para una prueba en mi unidad de prueba que prueba que myObject es un objeto que ha implementado mi interfaz ImyInterface.


-1

Tuve una situación en la que estaba pasando una variable a un método y no estaba seguro de si iba a ser una interfaz o un objeto.

Los objetivos fueron:

  1. Si item es una interfaz, cree una instancia de un objeto basado en esa interfaz con la interfaz como parámetro en la llamada del constructor.
  2. Si el artículo es un objeto, devuelve un valor nulo ya que el constructor de mis llamadas espera una interfaz y no quería que el código se acumulara.

Lo logré con lo siguiente:

    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

Esto debería funcionar :

MyInstace.GetType().GetInterfaces();

Pero bueno también:

if (obj is IMyInterface)

O incluso (no muy elegante):

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

99
La comprobación de la igualdad de typeof (IMyInterface) siempre fallará. Voto negativo
Jay Bazuzi el

Derecha. No hay instancias de una interfaz.
Rauhotz el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.