Does reflection in C#
offer a way to determine if some given System.Type
type models some interface?
public interface IMyInterface {}
public class MyType : IMyInterface {}
// should yield 'true'
typeof(MyType)./* ????? */MODELS_INTERFACE(IMyInterface);
You have a few choices:
typeof(IMyInterface).IsAssignableFrom(typeof(MyType)) typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface)) With C# 6 you can use typeof(MyType).GetInterface(nameof(IMyInterface)) != null
For a generic interface, it’s a bit different.
typeof(MyType).GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMyInterface<>))
typeof(IMyInterface).IsAssignableFrom(someclass.GetType());
or
typeof(IMyInterface).IsAssignableFrom(typeof(MyType));
someclass is IMyInterface
as that doesn't involve the cost of reflection at all. So, while not wrong, its not an ideal way to do it.
is
checks in both directions of the inheritance hierarchy whereas IsAssignableFrom
only checks upwards. Also, if you have an instance of an object, you should call IsInstanceOfType
(which also only looks upwards).
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;
}
I think this is the correct release, for three reasons:
It uses GetInterfaces and not IsAssignableFrom, it's faster since IsAssignableFrom eventually after several checks does call GetInterfaces. It iterates over the local array, so there will be no bounds checks. It uses the == operator which is defined for Type, so probably is safer than the Equals method (that the Contains call, will eventually use).
Use Type.IsAssignableTo
(as of .NET 5.0):
typeof(MyType).IsAssignableTo(typeof(IMyInterface));
As stated in a couple of comments IsAssignableFrom may be considered confusing by being "backwards".
I just did:
public static bool Implements<I>(this Type source) where I : class
{
return typeof(I).IsAssignableFrom(source);
}
I wish I could have said where I : interface
, but interface
is not a generic parameter constraint option. class
is as close as it gets.
Usage:
if(MyType.Implements<IInitializable>())
MyCollection.Initialize();
I just said Implements
because that's more intuitive. I always get IsAssignableFrom
flip-flopped.
return typeof(I).IsInterface && typeof(I).IsAssignableFrom(source);
to return false on any 'incorrect' usages of the method, that is; using it with a class type instead of an interface type, alternatively throw an exception if the type-parameter is not an interface. Though you could argue that a derived class 'implements' it's parent...
If you have a type or an instance you can easily check if they support a specific interface.
To test if an object implements a certain interface:
if(myObject is IMyInterface) {
// object myObject implements IMyInterface
}
To test if a type implements a certain interface:
if(typeof(IMyInterface).IsAssignableFrom(typeof(MyType))) {
// type MyType implements IMyInterface
}
If you got a generic object and want to do a cast as well as a check if the interface you cast to is implemented the code is:
var myCastedObject = myObject as IMyInterface;
if(myCastedObject != null) {
// object myObject implements IMyInterface
}
As someone else already mentioned: Benjamin Apr 10 '13 at 22:21"
It sure was easy to not pay attention and get the arguments for IsAssignableFrom backwards. I will go with GetInterfaces now :p –
Well, another way around is just to create a short extension method that fulfills, to some extent, the "most usual" way of thinking (and agreed this is a very little personal choice to make it slightly "more natural" based on one's preferences):
public static class TypeExtensions
{
public static bool IsAssignableTo(this Type type, Type assignableType)
{
return assignableType.IsAssignableFrom(type);
}
}
And why not going a bit more generic (well not sure if it is really that interesting, well I assume I'm just passing another pinch of 'syntaxing' sugar):
public static class TypeExtensions
{
public static bool IsAssignableTo(this Type type, Type assignableType)
{
return assignableType.IsAssignableFrom(type);
}
public static bool IsAssignableTo<TAssignable>(this Type type)
{
return IsAssignableTo(type, typeof(TAssignable));
}
}
I think it might be much more natural that way, but once again just a matter of very personal opinions:
var isTrue = michelleType.IsAssignableTo<IMaBelle>();
Boolean
=> bool
(I don't why I used to have some strict "fancy" rules of coding when I was younger).
Modifying Jeff's answer for optimal performance (thanks to performance test by Pierre Arnaud):
var type = typeof(MyType);
var implementsInterface = typeof(IMyInterface).IsAssignableFrom(type) && type.IsClass;
To find all types that implement an interface in a given Assembly
:
var implementations = typeof(TypeInTargetAssembly).Assembly.GetTypes()
.Where(t => typeof(IMyInterface).IsAssignableFrom(t) && t.IsClass);
Anyone searching for this might find the following extension method useful:
public static class TypeExtensions
{
public static bool ImplementsInterface(this Type type, Type @interface)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
if (@interface == null)
{
throw new ArgumentNullException(nameof(@interface));
}
var interfaces = type.GetInterfaces();
if (@interface.IsGenericTypeDefinition)
{
foreach (var item in interfaces)
{
if (item.IsConstructedGenericType && item.GetGenericTypeDefinition() == @interface)
{
return true;
}
}
}
else
{
foreach (var item in interfaces)
{
if (item == @interface)
{
return true;
}
}
}
return false;
}
}
xunit tests:
public class TypeExtensionTests
{
[Theory]
[InlineData(typeof(string), typeof(IList<int>), false)]
[InlineData(typeof(List<>), typeof(IList<int>), false)]
[InlineData(typeof(List<>), typeof(IList<>), true)]
[InlineData(typeof(List<int>), typeof(IList<>), true)]
[InlineData(typeof(List<int>), typeof(IList<int>), true)]
[InlineData(typeof(List<int>), typeof(IList<string>), false)]
public void ValidateTypeImplementsInterface(Type type, Type @interface, bool expect)
{
var output = type.ImplementsInterface(@interface);
Assert.Equal(expect, output);
}
}
Note that if you have a generic interface IMyInterface<T>
then this will always return false
:
typeof(IMyInterface<>).IsAssignableFrom(typeof(MyType)) /* ALWAYS FALSE */
This doesn't work either:
typeof(MyType).GetInterfaces().Contains(typeof(IMyInterface<>)) /* ALWAYS FALSE */
However, if MyType
implements IMyInterface<MyType>
this works and returns true
:
typeof(IMyInterface<MyType>).IsAssignableFrom(typeof(MyType))
However, you likely will not know the type parameter T
at runtime. A somewhat hacky solution is:
typeof(MyType).GetInterfaces()
.Any(x=>x.Name == typeof(IMyInterface<>).Name)
Jeff's solution is a bit less hacky:
typeof(MyType).GetInterfaces()
.Any(i => i.IsGenericType
&& i.GetGenericTypeDefinition() == typeof(IMyInterface<>));
Here's a extension method on Type
that works for any case:
public static class TypeExtensions
{
public static bool IsImplementing(this Type type, Type someInterface)
{
return type.GetInterfaces()
.Any(i => i == someInterface
|| i.IsGenericType
&& i.GetGenericTypeDefinition() == someInterface);
}
}
(Note that the above uses linq, which is probably slower than a loop.)
You can then do:
typeof(MyType).IsImplementing(IMyInterface<>)
IsAssignableFrom
is now moved to TypeInfo
:
typeof(ISMSRequest).GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo());
A correct answer is
typeof(MyType).GetInterface(nameof(IMyInterface)) != null;
However,
typeof(MyType).IsAssignableFrom(typeof(IMyInterface));
might return a wrong result, as the following code shows with string and 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}");
}
Results:
isConvertibleDirect: True
isConvertibleTypeAssignable: False
isConvertibleHasInterface: True
IsAssignableFrom
. Just like Benjamin and Ehouarn warn about.
what about
if(MyType as IMyInterface != null)
?
What about
typeof(IWhatever).GetTypeInfo().IsInterface
If you don't need to use reflection and you have an object, you can use this:
if(myObject is IMyInterface )
{
// it's implementing IMyInterface
}
Success story sharing
IsAssignableFrom
backwards. I will go withGetInterfaces
now :pIsAssignableFrom(t1)
variant is about 3x faster than theGetInterfaces().Contains(t2)
counterpart in my code.typeof(MyType).GetInterface(nameof(IMyInterface)) != null
for better type safety and refactoring.