Get all sub classes of generic abstract base class - c#

I have a generic base class and I eventually would have many derived classes.
I am trying to write a function which would return all these sub classes but everything I have tried so far has not worked.
public abstract class Index<T>
where T : class
{
public abstract string IndexName { get; }
public abstract string TypeName { get; }
public abstract Expression<Func<T, IConvertible>> IdFieldSelector { get; }
public string MakeSearchId(T item)
{
return ToSearchId(IdFieldSelector.Compile().Invoke(item));
}
public string MakeSearchId(IConvertible idValue)
{
return ToSearchId(idValue);
}
private static string ToSearchId(IConvertible idValue)
{
return idValue.ToString(CultureInfo.InvariantCulture);
}
}
sample subclass:
public class SurveyChangedIndex : Index<SurveyChanged>
{
public override string IndexName => "reviews";
public override string TypeName => "review";
public override Expression<Func<SurveyChanged, IConvertible>> IdFieldSelector => sc => sc.SurveyResponseId;
}
sample function:
var indexBase = typeof(Index<>);
var indexes = Assembly.GetAssembly(indexBase)
.GetTypes()
.Where(type =>
type != indexBase &&
!type.IsInterface &&
!type.IsAbstract &&
type.BaseType == indexBase)
.ToList();

You can do the following (C# 7 syntax follows):
public static IEnumerable<Type> GetAllDescendantsOf(
this Assembly assembly,
Type genericTypeDefinition)
{
IEnumerable<Type> GetAllAscendants(Type t)
{
var current = t;
while (current.BaseType != typeof(object))
{
yield return current.BaseType;
current = current.BaseType;
}
}
if (assembly == null)
throw new ArgumentNullException(nameof(assembly));
if (genericTypeDefinition == null)
throw new ArgumentNullException(nameof(genericTypeDefinition));
if (!genericTypeDefinition.IsGenericTypeDefinition)
throw new ArgumentException(
"Specified type is not a valid generic type definition.",
nameof(genericTypeDefinition));
return assembly.GetTypes()
.Where(t => GetAllAscendants(t).Any(d =>
d.IsGenericType &&
d.GetGenericTypeDefinition()
.Equals(genericTypeDefinition)));
}
This will return any type that inherits directly or indirectly from the specified generic type definition.
In the following scenario:
class Base { }
class Base<T>: Base { }
class Foo : Base<int> { }
class Bar : Base<string> { }
class Frob : Bar { }
class FooBar: Base { };
var genericTypeDefinition = typeof(Base<>);
var types = Assembly.GetExecutingAssembly()
.GetAllDescendantsOf(genericTypeDefinition)));
GetAllDescendantsOf will output Foo, Bar and Frob.

This should solve your code:
var indexes = Assembly.GetAssembly(indexBase)
.GetTypes()
.Where(type =>
type != indexBase &&
!type.IsInterface &&
!type.IsAbstract &&
type.BaseType.IsAssignableFrom(indexBase))
.ToList();

This worked for me:
var indexes = Assembly.GetAssembly(indexBase)
.GetTypes()
.Where(IsIndexType)
.ToArray();
with
private bool IsIndexType(Type type)
{
var indexDefinition = typeof(Index<>).GetGenericTypeDefinition();
return !type.IsAbstract
&& type.IsClass
&& type.BaseType is not null
&& type.BaseType.IsGenericType
&& type.BaseType.GetGenericTypeDefinition() == indexDefinition;
}

Related

Adding a list of types to service builder

I am trying to take a namespace find all the classes that end with service then add them as a singleton to my service.
foreach(Type serviceClass in GetTypesInNamespace(Assembly.GetExecutingAssembly(), "MyProject.Services"))
{
services.AddSingleton<serviceClass.GetType()>;
}
This does not compile, so any help would be appreciated.
The best approach that I found is based on this.
Would required some mother methods and classes:
You need to call this inside you Configure:
services.RegisterAssemblyPublicNonGenericClasses()
.Where(c => c.Namespace == "")
.AsPublicImplementedInterfaces();
Create this class:
public class AutoRegisteredResult
{
internal AutoRegisteredResult(Type classType, Type interfaceType)
{
Class = classType;
Interface = interfaceType;
}
public Type Class { get; }
public Type Interface { get; }
}
And these methods:
public static IEnumerable<Type> RegisterAssemblyPublicNonGenericClasses(this IServiceCollection services,
params Assembly[] assemblies)
{
if (assemblies.Length == 0)
assemblies = new[] { Assembly.GetCallingAssembly() };
var allPublicTypes = assemblies.SelectMany(x => x.GetExportedTypes()
.Where(y => y.IsClass && !y.IsAbstract && !y.IsGenericType && !y.IsNested));
return allPublicTypes;
}
public static IList<AutoRegisteredResult> AsPublicImplementedInterfaces(this IEnumerable<Type> autoRegData)
{
var result = new List<AutoRegisteredResult>();
foreach (var classType in autoRegData)
{
var interfaces = classType.GetTypeInfo().ImplementedInterfaces;
foreach (var infc in interfaces)
{
result.Add(new AutoRegisteredResult(classType, infc));
}
}
return result;
}

How do I check if an object is an ICollection<T>? [duplicate]

Assume the following type definitions:
public interface IFoo<T> : IBar<T> {}
public class Foo<T> : IFoo<T> {}
How do I find out whether the type Foo implements the generic interface IBar<T> when only the mangled type is available?
By using the answer from TcKs it can also be done with the following LINQ query:
bool isBar = foo.GetType().GetInterfaces().Any(x =>
x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IBar<>));
You have to go up through the inheritance tree and find all the interfaces for each class in the tree, and compare typeof(IBar<>) with the result of calling Type.GetGenericTypeDefinition if the interface is generic. It's all a bit painful, certainly.
See this answer and these ones for more info and code.
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;
}
}
As a helper method extension
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);
}
Example usage:
var testObject = new Dictionary<int, object>();
result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true!
I'm using a slightly simpler version of #GenericProgrammers extension method:
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));
}
Usage:
if (!featureType.Implements<IFeature>())
throw new InvalidCastException();
To tackle the type system completely, I think you need to handle recursion, e.g. IList<T> : ICollection<T> : IEnumerable<T>, without which you wouldn't know that IList<int> ultimately implements IEnumerable<>.
/// <summary>Determines whether a type, like IList<int>, implements an open generic interface, like
/// IEnumerable<>. 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));
}
In case you wanted an extension method that would support generic base types as well as interfaces, I've expanded sduplooy's answer:
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);
}
You have to check against a constructed type of the generic interface.
You will have to do something like this:
foo is IBar<String>
because IBar<String> represents that constructed type. The reason you have to do this is because if T is undefined in your check, the compiler doesn't know if you mean IBar<Int32> or IBar<SomethingElse>.
First of all public class Foo : IFoo<T> {} does not compile because you need to specify a class instead of T, but assuming you do something like public class Foo : IFoo<SomeClass> {}
then if you do
Foo f = new Foo();
IBar<SomeClass> b = f as IBar<SomeClass>;
if(b != null) //derives from IBar<>
Blabla();
Method to check if the type inherits or implements a generic type:
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));
}
Try the following extension.
public static bool Implements(this Type #this, Type #interface)
{
if (#this == null || #interface == null) return false;
return #interface.GenericTypeArguments.Length>0
? #interface.IsAssignableFrom(#this)
: #this.GetInterfaces().Any(c => c.Name == #interface.Name);
}
To test it. create
public interface IFoo { }
public interface IFoo<T> : IFoo { }
public interface IFoo<T, M> : IFoo<T> { }
public class Foo : IFoo { }
public class Foo<T> : IFoo { }
public class Foo<T, M> : IFoo<T> { }
public class FooInt : IFoo<int> { }
public class FooStringInt : IFoo<string, int> { }
public class Foo2 : Foo { }
and the test method
public void Test()
{
Console.WriteLine(typeof(Foo).Implements(typeof(IFoo)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<>)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<int>)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<string>)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<,>)));
Console.WriteLine(typeof(FooStringInt).Implements(typeof(IFoo<,>)));
Console.WriteLine(typeof(FooStringInt).Implements(typeof(IFoo<string,int>)));
Console.WriteLine(typeof(Foo<int,string>).Implements(typeof(IFoo<string>)));
}
var genericType = typeof(ITest<>);
Console.WriteLine(typeof(Test).GetInterfaces().Any(x => x.GetGenericTypeDefinition().Equals(genericType))); // prints: "True"
interface ITest<T> { };
class Test : ITest<string> { }
This worked for me.
You can add the below extension method:
public static TypeExtension
{
public static bool IsImplement<T>(this Type type)
{
return type.IsImplement(typeof(T));
}
public static bool IsImplement(this Type type, Type interfaceType)
{
if (!interfaceType.IsInterface)
throw new InvalidOperationException("Only interfaces can be implemented.");
return type.IsAssignableTo(interfaceType) ||
interfaceType.IsGenericType && type.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == interfaceType.GetGenericTypeDefinition());
}
}
There shouldn't be anything wrong the following:
bool implementsGeneric = (anObject.Implements("IBar`1") != null);
For extra credit you could catch AmbiguousMatchException if you wanted to provide a specific generic-type-parameter with your IBar query.

Obtaining a list of subtypes of generic class

I have a generic class with many subtypes:
public abstract class MyClass<T> : MyBaseClass where T : class
{...}
public class MySubClassA : MyClass<A>
{...}
public class MySubClassB : MyClass<B>
{...}
Is there an easy way to search for subclasses of MyClass and obtain an IEnumerable<Type> containing MySubClassA and MySubClassB?
I have used this method before, but I am not sure how to adapt it for use with generics:
public static IEnumerable<Type> GetSubTypesOf(Type t, bool baseAssemblyOnly = false)
{
List<Type> types = new List<Type>();
Assembly[] searchAssemblies = baseAssemblyOnly
? new[] { Assembly.GetAssembly(t) }
: AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly a in searchAssemblies)
{
types.AddRange(a.GetTypes()
.Where(myType => myType.IsClass
&& !myType.IsAbstract
&& myType.IsSubclassOf(t)));
}
return types;
}
This is a bit complicated since you have to search the base types of a type to find one which matches the open generic type definition of MyClass<>. You can define a couple of helper methods:
public static IEnumerable<Type> BaseTypesOf(Type t)
{
while (t != null)
{
yield return t;
t = t.BaseType;
}
}
public static Type FindGenericBaseTypeOf(Type t, Type openType)
{
return BaseTypesOf(t)
.FirstOrDefault(bt => bt.IsGenericType && bt.GetGenericTypeDefinition() == openType);
}
then you can apply them to the incoming sequence of types to search e.g.
var types = Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsClass && !t.IsAbstract)
.Select(t => new { Type = t, GenericBase = FindGenericBaseTypeOf(t, typeof(MyClass<>)) })
.Where(ts => ts.GenericBase != null)
.Select(ts => ts.GenericBase.GetGenericArguments().First())
.ToArray();
The problem is that when you pass typeof(MyClass<>) for the t parameter, you are not passing an instantiated generic type, but a generic type definition. This means that none of your classes would respond to IsSubclassOf(t).
You can fix your code as follows:
List<Type> types = searchAssemblies
.SelectMany(a =>
a.GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && HasGenericBase(myType, t))
).ToList();
...
private static bool HasGenericBase(Type myType, Type t) {
Debug.Assert(t.IsGenericTypeDefinition);
while (myType != typeof(object)) {
if (myType.IsGenericType && myType.GetGenericTypeDefinition() == t) {
return true;
}
myType = myType.BaseType;
}
return false;
}

Automatically Registering All Implementations of a Generic Interface

My current registration code:
Assembly web = Assembly.Load("MyAssembly");
types.AddRange(web.GetTypes());
//etc.
foreach (var theInterface in types.Where(t => t.IsInterface))
{
var assignableType = types.Where(t => theInterface.IsAssignableFrom(t) && t != theInterface);
foreach (var type in assignableType)
{
container.RegisterType(theInterface, type);
}
}
My generic interface and its implementations:
public interface IDomainEventHandler<in T>
{
void Handle(T message);
}
public class DomainEventHandler1 : IDomainEventHandler<PhilTest1>
{
public void Handle(PhilTest1 message)
{
throw new System.NotImplementedException();
}
}
public class DomainEventHandler2 : IDomainEventHandler<PhilTest2>
{
public void Handle(PhilTest2 message)
{
throw new System.NotImplementedException();
}
}
public class DomainEventHandler3 : IDomainEventHandler<PhilTest2>
{
public void Handle(PhilTest2 message)
{
throw new System.NotImplementedException();
}
}
public class PhilTest1
{
}
public class PhilTest2
{
}
Here is a simplified version of how I would resolve:
IEnumerable<IDomainEventHandler<PhilTest2>> listeners = Container.ResolveAll<IDomainEventHandler<PhilTest2>>();
IEnumerable<IDomainEventHandler<PhilTest1>> listeners2 = Container.ResolveAll<IDomainEventHandler<PhilTest1>>();
This doesn't work--listeners and listeners2 are both empty after resolving. This is not unexpected.
In Windsor, I could do something like this:
container.Register(AllTypes.FromAssemblyNamed("MyAssembly").BasedOn(typeof(IDomainEventHandler<>)).WithService.Base());
How would I register all instances of IDomainEventHandler in Unity? I'd prefer to keep the existing registration code intact (if possible).
A bit painful, but I finally pieced it together via googling and debugging:
Registration:
IEnumerable<Type> handlers = types.Where(t => IsAssignableToGenericType(t, typeof(IDomainEventHandler<>)) && !t.IsInterface);
foreach (var handler in handlers)
{
container.AddNewExtension<OpenGenericExtension>()
.Configure<IOpenGenericExtension>()
.RegisterClosedImpl(typeof (IDomainEventHandler<>), handler);
}
IsAssignableToGenericType method:
private static bool IsAssignableToGenericType(Type givenType, Type genericType)
{
var interfaceTypes = givenType.GetInterfaces();
foreach (var it in interfaceTypes)
{
if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
return true;
}
if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
return true;
Type baseType = givenType.BaseType;
if (baseType == null) return false;
return IsAssignableToGenericType(baseType, genericType);
}
And the Extension. Note that if I didn't use a name for the registration, only one type would remain registered. I believe this is by design?
public interface IOpenGenericExtension : IUnityContainerExtensionConfigurator
{
void RegisterClosedImpl(Type openGenericInterface, Type closedType);
}
public class OpenGenericExtension : UnityContainerExtension, IOpenGenericExtension
{
protected override void Initialize() {}
public void RegisterClosedImpl(Type openGenericInterface, Type closedType)
{
closedType.GetInterfaces().Where(x => x.IsGenericType)
.Where(x => x.GetGenericTypeDefinition() == openGenericInterface)
.ToList()
.ForEach(x => Container.RegisterType(x, closedType, closedType.Name));
}
}

How to determine if a type implements a specific generic interface type

Assume the following type definitions:
public interface IFoo<T> : IBar<T> {}
public class Foo<T> : IFoo<T> {}
How do I find out whether the type Foo implements the generic interface IBar<T> when only the mangled type is available?
By using the answer from TcKs it can also be done with the following LINQ query:
bool isBar = foo.GetType().GetInterfaces().Any(x =>
x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IBar<>));
You have to go up through the inheritance tree and find all the interfaces for each class in the tree, and compare typeof(IBar<>) with the result of calling Type.GetGenericTypeDefinition if the interface is generic. It's all a bit painful, certainly.
See this answer and these ones for more info and code.
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;
}
}
As a helper method extension
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);
}
Example usage:
var testObject = new Dictionary<int, object>();
result = testObject.GetType().Implements(typeof(IDictionary<int, object>)); // true!
I'm using a slightly simpler version of #GenericProgrammers extension method:
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));
}
Usage:
if (!featureType.Implements<IFeature>())
throw new InvalidCastException();
To tackle the type system completely, I think you need to handle recursion, e.g. IList<T> : ICollection<T> : IEnumerable<T>, without which you wouldn't know that IList<int> ultimately implements IEnumerable<>.
/// <summary>Determines whether a type, like IList<int>, implements an open generic interface, like
/// IEnumerable<>. 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));
}
In case you wanted an extension method that would support generic base types as well as interfaces, I've expanded sduplooy's answer:
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);
}
You have to check against a constructed type of the generic interface.
You will have to do something like this:
foo is IBar<String>
because IBar<String> represents that constructed type. The reason you have to do this is because if T is undefined in your check, the compiler doesn't know if you mean IBar<Int32> or IBar<SomethingElse>.
First of all public class Foo : IFoo<T> {} does not compile because you need to specify a class instead of T, but assuming you do something like public class Foo : IFoo<SomeClass> {}
then if you do
Foo f = new Foo();
IBar<SomeClass> b = f as IBar<SomeClass>;
if(b != null) //derives from IBar<>
Blabla();
Method to check if the type inherits or implements a generic type:
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));
}
Try the following extension.
public static bool Implements(this Type #this, Type #interface)
{
if (#this == null || #interface == null) return false;
return #interface.GenericTypeArguments.Length>0
? #interface.IsAssignableFrom(#this)
: #this.GetInterfaces().Any(c => c.Name == #interface.Name);
}
To test it. create
public interface IFoo { }
public interface IFoo<T> : IFoo { }
public interface IFoo<T, M> : IFoo<T> { }
public class Foo : IFoo { }
public class Foo<T> : IFoo { }
public class Foo<T, M> : IFoo<T> { }
public class FooInt : IFoo<int> { }
public class FooStringInt : IFoo<string, int> { }
public class Foo2 : Foo { }
and the test method
public void Test()
{
Console.WriteLine(typeof(Foo).Implements(typeof(IFoo)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<>)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<int>)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<string>)));
Console.WriteLine(typeof(FooInt).Implements(typeof(IFoo<,>)));
Console.WriteLine(typeof(FooStringInt).Implements(typeof(IFoo<,>)));
Console.WriteLine(typeof(FooStringInt).Implements(typeof(IFoo<string,int>)));
Console.WriteLine(typeof(Foo<int,string>).Implements(typeof(IFoo<string>)));
}
var genericType = typeof(ITest<>);
Console.WriteLine(typeof(Test).GetInterfaces().Any(x => x.GetGenericTypeDefinition().Equals(genericType))); // prints: "True"
interface ITest<T> { };
class Test : ITest<string> { }
This worked for me.
You can add the below extension method:
public static TypeExtension
{
public static bool IsImplement<T>(this Type type)
{
return type.IsImplement(typeof(T));
}
public static bool IsImplement(this Type type, Type interfaceType)
{
if (!interfaceType.IsInterface)
throw new InvalidOperationException("Only interfaces can be implemented.");
return type.IsAssignableTo(interfaceType) ||
interfaceType.IsGenericType && type.GetInterfaces()
.Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == interfaceType.GetGenericTypeDefinition());
}
}
There shouldn't be anything wrong the following:
bool implementsGeneric = (anObject.Implements("IBar`1") != null);
For extra credit you could catch AmbiguousMatchException if you wanted to provide a specific generic-type-parameter with your IBar query.

Categories

Resources