Qué reflexión en C#ofrecer una manera de determinar si algunos dados System.Typemodelos tipo de alguna de las interfaces?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
c#
reflection
interface
Yippie-Ki-Yay
fuente
fuente

IsAssignableFromrevés. IréGetInterfacesahora con : pIsAssignableFrom(t1)variante es aproximadamente 3 veces más rápida que laGetInterfaces().Contains(t2)contraparte en mi código.typeof(MyType).GetInterface(nameof(IMyInterface)) != nullmejorar la seguridad de los tipos y la refactorización.Uso
Type.IsAssignableFrom:fuente
o
fuente
someclass is IMyInterfaceque no implica el costo de la reflexión en absoluto. Entonces, aunque no está mal, no es una forma ideal de hacerlo.isverifica en ambas direcciones de la jerarquía de herencia, mientras queIsAssignableFromsolo verifica hacia arriba. Además, si tiene una instancia de un objeto, debe llamarIsInstanceOfType(que también solo mira hacia arriba).Creo que esta es la versión correcta, por tres razones:
fuente
Lo acabo de hacer:
Desearía haberlo dicho
where I : interface, perointerfaceno es una opción genérica de restricción de parámetros.classestá lo más cerca posible.Uso:
Solo dije
Implementsporque eso es más intuitivo. Siempre meIsAssignableFromflip-flop.fuente
return typeof(I).IsInterface && typeof(I).IsAssignableFrom(source);para devolver falso en cualquier uso 'incorrecto' del método, es decir; utilizándolo con un tipo de clase en lugar de un tipo de interfaz, alternativamente, arroje una excepción si el parámetro tipo no es una interfaz. Aunque podría argumentar que una clase derivada 'implementa' es su padre ...Modificación de la respuesta de Jeff para un rendimiento óptimo (gracias a la prueba de rendimiento de Pierre Arnaud):
Para buscar todos los tipos que implementan una interfaz en un determinado
Assembly:fuente
Como alguien más ya mencionó: Benjamin Abr 10 '13 a las 22:21 "
Bueno, otra forma de evitarlo es crear un método de extensión breve que cumpla, hasta cierto punto, la forma de pensar "más habitual" (y acordó que esta es una elección personal muy pequeña para que sea un poco "más natural" en función de las preferencias personales) ):
¿Y por qué no ser un poco más genérico?
Creo que podría ser mucho más natural de esa manera, pero una vez más solo es cuestión de opiniones muy personales:
fuente
Boolean=>bool(no sé por qué solía tener algunas reglas estrictas "elegantes" de codificación cuando era más joven).Si tiene un tipo o una instancia, puede verificar fácilmente si son compatibles con una interfaz específica.
Para probar si un objeto implementa una determinada interfaz:
Para probar si un tipo implementa una determinada interfaz:
Si tiene un objeto genérico y desea realizar una conversión, así como verificar si la interfaz a la que está implementado, el código es:
fuente
IsAssignableFromahora se mueve aTypeInfo:fuente
Cualquiera que busque esto puede encontrar útil el siguiente método de extensión:
pruebas de xunit:
fuente
qué pasa
?
fuente
Qué pasa
fuente
Una respuesta correcta es
Sin embargo,
podría devolver un resultado incorrecto, como se muestra en el siguiente código con string e IConvertible:
Resultados:
fuente
IsAssignableFrom. Tal como lo advierten Benjamin y Ehouarn.Tenga en cuenta que si tiene una interfaz genérica
IMyInterface<T>, esto siempre devolveráfalse:Esto tampoco funciona:
Sin embargo, si
MyTypeimplementaIMyInterface<MyType>esto funciona y devuelvetrue:Sin embargo, es probable que no conozca el parámetro de tipo
Ten tiempo de ejecución . Una solución algo hacky es:La solución de Jeff es un poco menos hacky:
Aquí hay un método de extensión
Typeque funciona para cualquier caso:(Tenga en cuenta que lo anterior usa linq, que probablemente es más lento que un bucle).
Entonces puedes hacer:
fuente