Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if a class implements a very specific interface

There are tons of questions about this topic, but I have a slightly altered version of it.

We have the following code:

interface IFoo { }
interface IBar : IFoo { }
class Foo : IFoo { }
class Bar : IBar { }

bool Implements_IFoo(Type type) { /* ??? */ }

Now, the twist of the story: the method Implements_IFoo should only return true when the Type implements IFoo only and not any of the interfaces derived from IFoo. To illustrate here are some examples of this method:

Implements_IFoo(typeof(Foo)); // Should return true

Implements_IFoo(typeof(Bar)); // Should return false as Bar type 
                              // implements an interface derived from IFoo

Note that there can be numerous interfaces derived from IFoo and you do not necessarily know about their existence.

The obvious method is to find all interfaces derived from IFoo through reflection and then just check the typeof(Bar).GetInterfaces() is any of those are present in there. But I was wondering if someone can come up with a more elegant solution.

PS The question originates from some code I found that uses this check on classes (if(obj.GetType() == typeof(BaseClass)) { ... }). We are replacing classes with interfaces now that particular code. Also, just in case - I am implementing this check as a boolean flag, so this question is purely hypothetical.

like image 898
Jefim Avatar asked Apr 27 '12 13:04

Jefim


People also ask

How do you check whether a class implements an interface?

isInterface() method The isArray() method of the Class class is used to check whether a class is an interface or not. This method returns true if the given class is an interface. Otherwise, the method returns false , indicating that the given class is not an interface.

Can we know which interfaces are implemented by a class?

Your class can implement more than one interface, so the implements keyword is followed by a comma-separated list of the interfaces implemented by the class. By convention, the implements clause follows the extends clause, if there is one.

When a class implements an interface it must?

To implement an interface, a class must specify that implements that interface and it must also provide implementations for all of the methods defined in the interface. If a class fails to implement one or more abstract methods from the interface, the compiler will complain.

How do I know which classes implement an interface in eclipse?

Open Java Search, enter the interface name, click "Implementors" and you will "find which classes implement a particular interface."


2 Answers

I had a try because it sounded like fun, and this works for your example:

bool ImplementsIFooDirectly(Type t) {
    if (t.BaseType != null && ImplementsIFooDirectly(t.BaseType)) { 
        return false; 
    }
    foreach (var intf in t.GetInterfaces()) {
        if (ImplementsIFooDirectly(intf)) { 
            return false;
        }
    }
    return t.GetInterfaces().Any(i => i == typeof(IFoo));
}

results:

ImplementsIFooDirectly(typeof(IFoo)); // false
ImplementsIFooDirectly(typeof(Bar)); // false
ImplementsIFooDirectly(typeof(Foo)); // true
ImplementsIFooDirectly(typeof(IBar)); // true

It doesn't look for all interfaces derived from IFoo, it just travels up the inheritance / interface implementation chain and see if IFoo is present at any level other than the exact level of the type.

It also detects if the interface is inherited via base type. Not sure if that is what you want.

Still, as others have said already, if this is really a requirement for you, then you might have a problem with your design. (EDIT: Just noticed your question is purely hypothetical. Then it's fine of course :))

like image 140
Botz3000 Avatar answered Oct 13 '22 14:10

Botz3000


See the following site for examples on how this can be implemented;

C# is keyword usage

Essentially you can use the 'is' keyword to determine whether the object inhabits a class type as part of it's class inheritance stack.

class Director  : Owner { }
class Developer : Employee { }
..
var dave = new Developer();
var steve = new Director();
var isEmployee = dave is Employee; // true
var isAlsoEmploye = steve is Employee; // false

In line with your example function:

bool Implements_Type(object instance, Type type) { 
return instance is type;
}
like image 21
Brian Scott Avatar answered Oct 13 '22 14:10

Brian Scott