uso usar usan una que programacion porque orientada objetos las interfaz interfaces implementacion ejemplos como atributos c# .net reflection

c# - usar - Cómo determinar si un tipo implementa un tipo de interfaz genérico específico



usar interface c# (11)

Al usar la respuesta de TcKs, también se puede hacer con la siguiente consulta LINQ:

bool isBar = foo.GetType().GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IBar<>));

Supongamos las siguientes definiciones de tipo:

public interface IFoo<T> : IBar<T> {} public class Foo<T> : IFoo<T> {}

¿Cómo puedo saber si el tipo Foo implementa la interfaz genérica IBar<T> cuando solo está disponible el tipo mutilado?


Como una extensión de método auxiliar

public static bool Implements<I>(this Type type, I @interface) where I : class { if(((@interface as Type)==null) || !(@interface as Type).IsInterface) throw new ArgumentException("Only interfaces can be ''implemented''."); return (@interface as Type).IsAssignableFrom(type); }

Ejemplo de uso:

var testObject = new Dictionary<int, object>(); result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true!


En caso de que quisiera un método de extensión que admitiera tipos base genéricos así como interfaces, he expandido la respuesta de sduplooy:

public static bool InheritsFrom(this Type t1, Type t2) { if (null == t1 || null == t2) return false; if (null != t1.BaseType && t1.BaseType.IsGenericType && t1.BaseType.GetGenericTypeDefinition() == t2) { return true; } if (InheritsFrom(t1.BaseType, t2)) return true; return (t2.IsAssignableFrom(t1) && t1 != t2) || t1.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == t2); }


En primer lugar, public class Foo : IFoo<T> {} no se compila porque necesitas especificar una clase en lugar de T, pero asumiendo que haces algo como public class Foo : IFoo<SomeClass> {}

entonces si lo haces

Foo f = new Foo(); IBar<SomeClass> b = f as IBar<SomeClass>; if(b != null) //derives from IBar<> Blabla();


Estoy usando una versión un poco más simple del método de extensión @GenericProgrammers:

public static bool Implements<TInterface>(this Type type) where TInterface : class { var interfaceType = typeof(TInterface); if (!interfaceType.IsInterface) throw new InvalidOperationException("Only interfaces can be implemented."); return (interfaceType.IsAssignableFrom(type)); }

Uso:

if (!featureType.Implements<IFeature>()) throw new InvalidCastException();


Método para verificar si el tipo hereda o implementa un tipo genérico:

public static bool IsTheGenericType(this Type candidateType, Type genericType) { return candidateType != null && genericType != null && (candidateType.IsGenericType && candidateType.GetGenericTypeDefinition() == genericType || candidateType.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == genericType) || candidateType.BaseType != null && candidateType.BaseType.IsTheGenericType(genericType)); }


No debe haber nada malo en lo siguiente:

bool implementsGeneric = (anObject.Implements("IBar`1") != null);

Para obtener crédito adicional, puede obtener AmbiguousMatchException si desea proporcionar un parámetro de tipo genérico específico con su consulta IBar.


Para abordar completamente el sistema de tipos, creo que necesita manejar la recursión, por ejemplo, IList<T> : ICollection<T> : IEnumerable<T> , sin el cual no sabría que IList<int> implementa finalmente IEnumerable<> .

/// <summary>Determines whether a type, like IList&lt;int&gt;, implements an open generic interface, like /// IEnumerable&lt;&gt;. Note that this only checks against *interfaces*.</summary> /// <param name="candidateType">The type to check.</param> /// <param name="openGenericInterfaceType">The open generic type which it may impelement</param> /// <returns>Whether the candidate type implements the open interface.</returns> public static bool ImplementsOpenGenericInterface(this Type candidateType, Type openGenericInterfaceType) { Contract.Requires(candidateType != null); Contract.Requires(openGenericInterfaceType != null); return candidateType.Equals(openGenericInterfaceType) || (candidateType.IsGenericType && candidateType.GetGenericTypeDefinition().Equals(openGenericInterfaceType)) || candidateType.GetInterfaces().Any(i => i.IsGenericType && i.ImplementsOpenGenericInterface(openGenericInterfaceType)); }


Tienes que verificar contra un tipo construido de la interfaz genérica.

Tendrás que hacer algo como esto:

foo is IBar<String>

porque IBar<String> representa ese tipo construido. La razón por la que debe hacer esto es porque si T no está definido en su cheque, el compilador no sabe si se IBar<Int32> o IBar<SomethingElse> .


typeof(IBar<>) ir a través del árbol de herencia y encontrar todas las interfaces para cada clase en el árbol, y comparar typeof(IBar<>) con el resultado de llamar a Type.GetGenericTypeDefinition si la interfaz es genérica. Es todo un poco doloroso, ciertamente.

Vea esta respuesta y estas para más información y código.


public interface IFoo<T> : IBar<T> {} public class Foo : IFoo<Foo> {} var implementedInterfaces = typeof( Foo ).GetInterfaces(); foreach( var interfaceType in implementedInterfaces ) { if ( false == interfaceType.IsGeneric ) { continue; } var genericType = interfaceType.GetGenericTypeDefinition(); if ( genericType == typeof( IFoo<> ) ) { // do something ! break; } }