Reputation: 35679
I want to test if a type implements one of a set of interfaces.
ViewData["IsInTheSet"] =
model.ImplementsAny<IInterface1, IInterface2, IInterface3, IInterface4>();
I have written the following extension methods to handle this.
Is there a more extensible way to write the following code? I would prefer not to have to write a new method while still leveraging generics.
public static bool Implements<T>(this object obj)
{
Check.Argument.IsNotNull(obj, "obj");
return (obj is T);
}
public static bool ImplementsAny<T>(this object obj)
{
return obj.Implements<T>();
}
public static bool ImplementsAny<T,V>(this object obj)
{
if (Implements<T>(obj))
return true;
if (Implements<V>(obj))
return true;
return false;
}
public static bool ImplementsAny<T,V,W>(this object obj)
{
if (Implements<T>(obj))
return true;
if (Implements<V>(obj))
return true;
if (Implements<W>(obj))
return true;
return false;
}
public static bool ImplementsAny<T, V, W, X>(this object obj)
{
if (Implements<T>(obj))
return true;
if (Implements<V>(obj))
return true;
if (Implements<W>(obj))
return true;
if (Implements<X>(obj))
return true;
return false;
}
Upvotes: 4
Views: 522
Reputation: 18965
The way I check if an interface has been implemented is:
public static bool IsImplementationOf(this Type checkMe, Type forMe)
{
if (forMe.IsGenericTypeDefinition)
return checkMe.GetInterfaces().Select(i =>
{
if (i.IsGenericType)
return i.GetGenericTypeDefinition();
return i;
}).Any(i => i == forMe);
return forMe.IsAssignableFrom(checkMe);
}
This could be easily extended to:
public static bool IsImplementationOf(this Type checkMe, params Type[] forUs)
{
return forUs.Any(forMe =>
{
if (forMe.IsGenericTypeDefinition)
return checkMe.GetInterfaces().Select(i =>
{
if (i.IsGenericType)
return i.GetGenericTypeDefinition();
return i;
}).Any(i => i == forMe);
return forMe.IsAssignableFrom(checkMe);
});
}
Or better yet:
public static bool IsImplementationOf(this Type checkMe, params Type[] forUs)
{
return forUs.Any(forMe => checkMe.IsImplementationOf(forMe));
}
Warning: Untested
Then just do a typeof
on your type parameters before passing them to this.
Upvotes: 1
Reputation: 245419
Why not use something like the following:
public static bool ImplementsAny(this object obj, params Type[] types)
{
foreach(var type in types)
{
if(type.IsAssignableFrom(obj.GetType())
return true;
}
return false;
}
Then you can call it like:
model.ImplementsAny(typeof(IInterface1),
typeof(IInterface2),
typeof(IInterface3),
typeof(IInterface4));
Upvotes: 5