Qué reflexión en C#
ofrecer una manera de determinar si algunos dados System.Type
modelos 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
IsAssignableFrom
revés. IréGetInterfaces
ahora 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)) != null
mejorar la seguridad de los tipos y la refactorización.Uso
Type.IsAssignableFrom
:fuente
o
fuente
someclass is IMyInterface
que no implica el costo de la reflexión en absoluto. Entonces, aunque no está mal, no es una forma ideal de hacerlo.is
verifica en ambas direcciones de la jerarquía de herencia, mientras queIsAssignableFrom
solo 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
, perointerface
no es una opción genérica de restricción de parámetros.class
está lo más cerca posible.Uso:
Solo dije
Implements
porque eso es más intuitivo. Siempre meIsAssignableFrom
flip-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
IsAssignableFrom
ahora 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
MyType
implementaIMyInterface<MyType>
esto funciona y devuelvetrue
:Sin embargo, es probable que no conozca el parámetro de tipo
T
en 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
Type
que 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