简体   繁体   中英

When enumerating a type's interfaces how do I get only those that are directly inherited?

I'm not sure of the exact terminology here. Basically, if I have a model like:

class Student : IDoSchool {}
class Freshman : Student {}
interface IDoSchool {}

What code would tell me that Freshman doesn't directly implement any interfaces and Student directly implements IDoSchool?

In other words (disregarding bad terminology) I want something like this:

typeof(Freshman).GetInterfaces(BindingFlags.DeclaredOnly); // nothing
typeof(Student).GetInterfaces(BindingFlags.DeclaredOnly); // IDoSchool

Thoughts?

I suspect the semantic of an interface is not in alignment with what you are trying to do.

An interface simply says that a class has to implemnt a list of members. The class inherits the interface but it is still the responsibilityy of the children class to implement the interface it inherited from the parent. Most of the case, the parent already provide an implementation, so we tend to perceive interface implementation as the same as inheritance but they are in fact totally different concepts.

In your case, the best you can do is retreive the interface mapping using GetInterfaceMap() and make sure all implementation of every memeber of the interface come from the parent, not from the child. This is the best you can do, but still, it won't exactly do what you are trying to do.

Also, is it possible in your case to use totally abstract classes instead of interfaces? You can't do multiple inheritance but maybe all your rules imply a very linear inheritance?

Just an idea...

You can get interfaces of the class, and interfaces of the base class. Then get the difference.

EDIT:

I've checked the idea, works:

public static Type[] GetDirectInterfaces(Type type)
{
    if (type.BaseType == null)
        return type.GetInterfaces();
    Type[] BaseInterfaces = type.BaseType.GetInterfaces();
    Type[] ThisInferfaces = type.GetInterfaces();
    return ThisInferfaces.Except(BaseInterfaces).ToArray();
}

If the amount of interfaces is huge and the execution time is crucial, you can create a separate static class with dictionary to cache results.

Sorry for posting this as an answer, it's actually more a thought and a suggestion, but it wouldn't fit into a comment...

What if you have the following situation:

interface IA{
    void foo();
}
class CA : IA{
    public void foo(){
        Console.Writeline("Class A");
    }
}
class CB : CA, IA{
    public new void foo(){
        Console.Writeline("Class B");
    }
}

I guess CB should return IA among the 'directly implemented interfaces', but if you compare CB against CA you will see that they implement the same interfaces, so a find-the-differences approach would not work.
Before getting crazy looking for a solution, have you tried looking at the MSIL or at the code decompiled from Reflector to see if this is possible at all?

 typeof("the object").GetInterfaces().Count==0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM