c# - interfaces - que es una interfaz en programacion orientada a objetos
Cómo determinar si un tipo implementa una interfaz con reflexión de C# (11)
Como alguien más ya mencionó: Benjamin Abr 10 ''13 a las 22:21 "
Seguro que fue fácil no prestar atención y obtener los argumentos de IsAssignableFrom al revés. Iré con GetInterfaces ahora: p -
Bueno, otra forma es simplemente crear un método de extensión corto que cumpla, en cierta medida, con la forma de pensar "más habitual" (y acordamos que esta es una opción personal muy pequeña para hacerlo un poco más "natural" según las preferencias de cada uno ):
public static class TypeHelpers
{
public static Boolean IsAssignableTo(Type type, Type assignableType)
{
return assignableType.IsAssignableFrom(type);
}
}
public static class TypeExtensions
{
public static Boolean IsAssignableTo(this Type type, Type assignableType)
{
return TypeHelpers.IsAssignableTo(type, assignableType);
}
}
¿Y por qué no ir un poco más genérico (bueno, no estoy seguro de que sea realmente interesante, bueno, supongo que solo estoy pasando otra pizca de azúcar ''sintaxis''):
public static class TypeHelpers
{
public static Boolean IsAssignableTo(Type type, Type assignableType)
{
return assignableType.IsAssignableFrom(type);
}
public static Boolean IsAssignableTo<TAssignable>(Type type)
{
return TypeHelpers.IsAssignableTo(type, typeof(TAssignable));
}
}
public static class TypeExtensions
{
public static Boolean IsAssignableTo(this Type type, Type assignableType)
{
return TypeHelpers.IsAssignableTo(type, assignableType);
}
public static Boolean IsAssignableTo<TAssignable>(this Type type)
{
return TypeHelpers.IsAssignableTo<TAssignable>(type);
}
}
Creo que podría ser mucho más natural de esa manera, pero una vez más, es solo una cuestión de opiniones muy personales:
var isTrue = michelleType.IsAssignableTo<IMaBelle>();
¿La reflexión en C#
ofrece una manera de determinar si algún tipo de System.Type
dado modela alguna interfaz?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield ''true''
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
Lo acabo de hacer:
public static bool Implements<I>(this Type source) where I : class
{
return typeof(I).IsAssignableFrom(source);
}
Ojalá hubiera podido decir where I : interface
, pero la interface
no es una opción de restricción de parámetros genérica. class
es lo más cerca que se puede.
Uso:
if(MyType.Implements<IInitializable>())
MyCollection.Initialize();
Acabo de decir Implements
porque eso es más intuitivo. Siempre obtengo IsAssignableFrom
flip-flopped.
Modificación de la respuesta de Jeff para un rendimiento óptimo (gracias a la prueba de rendimiento de Pierre Arnaud):
var type = typeof(MyType);
var implementsInterface = typeof(IMyInterface).IsAssignableFrom(type) && type.IsClass;
Para encontrar todos los tipos que implementan una interfaz en un Assembly
dado:
var implementations = typeof(TypeInTargetAssembly).Assembly.GetTypes()
.Where(t => typeof(IMyInterface).IsAssignableFrom(t) && t.IsClass);
Qué pasa
typeof(IWhatever).GetTypeInfo().IsInterface
Tienes algunas opciones fuera de mi cabeza
typeof(IMyInterface).IsAssignableFrom(typeof(MyType))
typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface))
Para una interfaz genérica, es un poco diferente.
typeof(MyType).GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMyInterface<>))
Una respuesta correcta es
typeof(MyType).GetInterface(nameof(IMyInterface)) != null;
Sin embargo,
typeof(MyType).IsAssignableFrom(typeof(IMyInterface));
podría devolver un resultado incorrecto, como muestra el siguiente código con cadena e IConvertible:
static void TestIConvertible()
{
string test = "test";
Type stringType = typeof(string); // or test.GetType();
bool isConvertibleDirect = test is IConvertible;
bool isConvertibleTypeAssignable = stringType.IsAssignableFrom(typeof(IConvertible));
bool isConvertibleHasInterface = stringType.GetInterface(nameof(IConvertible)) != null;
Console.WriteLine($"isConvertibleDirect: {isConvertibleDirect}");
Console.WriteLine($"isConvertibleTypeAssignable: {isConvertibleTypeAssignable}");
Console.WriteLine($"isConvertibleHasInterface: {isConvertibleHasInterface}");
}
Resultados:
isConvertibleDirect: True
isConvertibleTypeAssignable: False
isConvertibleHasInterface: True
Utilice Type.IsAssignableFrom
:
typeof(IMyInterface).IsAssignableFrom(typeof(MyType));
qué pasa
if(MyType as IMyInterface != null)
?
IsAssignableFrom
ahora se mueve a TypeInfo
:
typeof(ISMSRequest).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo());
public static bool ImplementsInterface( this Type type, Type ifaceType ) {
Type[] intf = type.GetInterfaces();
for ( int i = 0; i < intf.Length; i++ ) {
if ( intf[ i ] == ifaceType ) {
return true;
}
}
return false;
}
Creo que esta es la versión correcta, por tres razones:
1) Utiliza GetInterfaces y no IsAssignableFrom, es más rápido ya que IsAssignableFrom finalmente después de varias verificaciones llama GetInterfaces.
2) Se itera sobre la matriz local, por lo que no habrá comprobaciones de límites.
3) Utiliza el operador == que se define para el Tipo, por lo que probablemente sea más seguro que el método de Igualdad (que finalmente utilizará la llamada Contiene).
typeof(IMyInterface).IsAssignableFrom(someclass.GetType());
o
typeof(IMyInterface).IsAssignableFrom(typeof(MyType));