Updated question given Andrew Hare's correct answer:
Given the following C# classes:
public class Bar : Foo, IDisposable
{
// implementation of Bar and IDisposable
}
public class Foo : IEnumerable<int>
{
// implementation of Foo and all its inherited interfaces
}
I want a method like the following that doesn't fail on the assertions (Note: you cannot change the assertions):
public void SomeMethod()
{
// This doesn't work
Type[] interfaces = typeof(Bar).GetInterfaces();
Debug.Assert(interfaces != null);
Debug.Assert(interfaces.Length == 1);
Debug.Assert(interfaces[0] == typeof(IDisposable));
}
Can someone help by fixing this method so the assertions don't fail?
Calling typeof(Bar).GetInterfaces()
doesn't work because it returns the entire interface hierarchy (i.e. interfaces
variable contains IEnumerable<int>
, IEnumerable
, and IDisposable
), not just the top level.
Try this:
using System.Linq;
public static class Extensions
{
public static Type[] GetTopLevelInterfaces(this Type t)
{
Type[] allInterfaces = t.GetInterfaces();
var selection = allInterfaces
.Where(x => !allInterfaces.Any(y => y.GetInterfaces().Contains(x)))
.Except(t.BaseType.GetInterfaces());
return selection.ToArray();
}
}
usage:
private void Check(Type t, Type i)
{
var interfaces = t.GetTopLevelInterfaces();
Debug.Assert(interfaces != null, "interfaces is null");
Debug.Assert(interfaces.Length == 1, "length is not 1");
Debug.Assert(interfaces[0] == i, "the expected interface was not found");
System.Console.WriteLine("\n{0}", t.ToString());
foreach (var intf in interfaces)
System.Console.WriteLine(" " + intf.ToString());
}
public void Run()
{
Check(typeof(Foo), typeof(IEnumerable<int>));
Check(typeof(Bar), typeof(IDisposable));
}
As noted elsewhere, this only works if the checked type explicitly implements a single interface. If you have more than one, then you need to change your Assert.
Andrew Hare is correct that you cannot retrieve the specified list of interfaces using reflection. However you can find the "top-level" interfaces by excluding any interfaces that are implied by others. You could implement it like this:
Type[] allInterfaces = typeof(Foo).GetInterfaces();
Type[] interfaces = allInterfaces
.Where(x => !allInterfaces.Any(y => y.GetInterfaces().Contains(x)))
.ToArray();
This passes your assertions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With