A C# reflection question: Is there any way for me to only get "declared" interfaces of a class?
interface I1 { } class A : I1 { } // get I1 class B : A, I1 { } // get I1 class C : A { } // get none
But GetInterfaces returns all a class's interfaces, so A, B, and C will all return I1. What I want is for C to return none.
Why do you want that? It kind of does make any sense. If any of parent classes implements interface, that means all derived classes implement it automatically too. There's no need to repeat implementing interface on derived classes. Meaning in any place where object of class C
is used - it can be passed to whoever expects I
interface. That's automatic.
Afaik there is no way to get such information via reflection functionality. Maybe this information is stored by compiler in .net metadata in binary (but I don't know if it is). If it is, then you'll need to parse that out of binary manually, or use something like Mono.Cecil for that.
Yeah, I know all derived classes implement their parent's interfaces. Afaik, Visual Studio uses reflection on a DLL to get all the types and members, so it can display them when you use "go to definition." I want to do a similar thing. VS knows which interfaces a class declares. Something like ILSpy also knows that. After digging around, it seems C# reflection isn't powerful enough to get this information. ILSpy seems to use Mono.Cecil as you suggested. Ildasm can also differentiate between B and C. It will say B "implements I1."
Possibly you could do some set operations to remove those found in the base class? Though that may still not be precise enough for your needs.
type.GetInterfaces() type.BaseType.GetInterfaces() // subtract these??
You could try to find or write a C# parser to do it at a higher-level, more like original/older Intellisense, if you have full access to the source.
Or you could try to utilize Roslyn, the compiler as an API/platform, which should allow getting much more metadata about types beyond what reflection gives you? YMMV, as I personally have never used this, so it may also not work - so just an FYI if you never heard of it.
That's what I did initially. A better way of doing this is using GetInterfaceMap. That way, you can also recognize classes that reimplement the interface. But it won't work for empty interfaces or if you declare but don't reimplement.