-2
Interface i1
End Interface

Public Class c1
    Implements i1
End Class

Public Class c2
    Inherits c1
End Class

How to determine (using reflection) that c2 have not implemented i1 ?

ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
codefox
  • 120
  • 8
  • 7
    If the code compiles, then as written clearly `c1` must have implemented `i1` (because otherwise you would have gotten a compilation error)... And `c2` inherits from `c1`, so it clearly implements `i1` – xanatos Mar 22 '16 at 11:07
  • 2
    With this code `c2` will **allways** implement the interface as it derives from `c1`. It is not clear what you want. Do you want to know if `c2` overwrites the interface-implementation provided by `c1`? – MakePeaceGreatAgain Mar 22 '16 at 11:09
  • Without reflection you can use `if TypeOf x Is IFoo Then` ... – BWA Mar 22 '16 at 11:09
  • The code won't compile if interface is not implemented – Alex Mar 22 '16 at 11:13
  • @xanatos c2 do not implement i1, just derive from c1 that have implemented i1. This is not the same – codefox Mar 22 '16 at 11:14
  • @Alex code compile without any implementtion of i1, implementation of i1 on c1 or c2, and implementation of i1 on c1 and c2 – codefox Mar 22 '16 at 11:16
  • @codefox c2 could re-Implements `i1` (by adding another `Implements i1`). Is this what you are trying to check? – xanatos Mar 22 '16 at 11:16
  • @xanatos I have code that reads types from assembly, and want to known where interface is implemented, but not by inheritance from base class – codefox Mar 22 '16 at 11:18
  • I think this is what you want (though it's c#): http://stackoverflow.com/questions/2932421/detect-if-a-method-was-overridden-using-reflection-c – René Vogt Mar 22 '16 at 11:18
  • when you inherit from a class you inherit interface implementations. you could explicitly put the same inhieratince on the derived class but that's redundant and isn't something you can detect or really should even care about – juharr Mar 22 '16 at 11:20
  • With the link I just posted, you can check if a method is overriden by `c2`. For what you want, you will need to check if _every_ method declared by `i1` is overridden by `c2`. – René Vogt Mar 22 '16 at 11:20

4 Answers4

0

I'll say that in the most generic case, while it is a metainformation that is surely contained in the assembly, it can't be discovered with .NET reflection.

public class DerivedWithInterface : BaseClass, IInterface
{
}

public class DerivedWithoutInterface : BaseClass
{
}

public interface IInterface
{
    void Method();
}

public class BaseClass : IInterface
{
    public void Method()
    {
        Console.WriteLine("C1");
    }
}

I've found no way to distinguish between DerivedWithInterface and DerivedWithoutInterface, BUT the IL code is different.

xanatos
  • 109,618
  • 12
  • 197
  • 280
0

To ask the main question, you can check whether a Class has an implemented interface in this way:

Dim hasInterface As Boolean = GetType(type).GetInterfaces.Contains(GetType(MyInterface))

A reflection example:

Dim ass As Assembly = Assembly.GetExecutingAssembly
Dim types As Type() = ass.GetTypes()

For Each t As Type In types

    If t.GetInterfaces.Contains(GetType(MyInterface)) Then
        Console.WrtieLine(String.Format("Found: {0}, t.Name))
    End If

Next t
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
0

In your case, you don't have to use reflection. C2 does implement your interface i1, because it inherits from C1 and therefore inherits of all the methods and properties that C1 provides. So if C1 provides an implementation for i1, so does C2. That is the magic of Object Oriented Programming...

Public Interface I1
  Function Method1() As String
End Interface

Public Class C1
  Implements I1

  Public Function Method1() As String Implements I1.Method1
     Return "Hello"
  End Function
End Class


Public Class C2
  Inherits C1
End Class

'Somewhere in your code
Dim Test As New C2()
Test.Method1() 'It does work, so C2 Implements I1 because it inherits from C1

You can also say, if you want to Reimplement the interface :

Public Class C2
  Inherits C1
  Implements I1

  'You have to declare it Overload because this function already exists
  Public Overloads Function Method1() as String Implements I1.Method1
    Return "Hello From C2"
  End Function
End Class

But what it will do is that it will replace the first implementation by the one defined in C1. And since it is a replacement there is no way to know it...

Dim C As New C2()
Dim T = C.GetType()
For Each I In T.GetInterfaces()
    Dim map = T.GetInterfaceMap(I)
    Dim target = map.TargetType
    MessageBox.Show(target.Name) 'Will always display C2, whether or not you reimplement it.
Next
Martin Verjans
  • 4,675
  • 1
  • 21
  • 48
  • but I may write: Public Class c2 Inherits c1 implements i1 End Class, and can't figure by reflection if i1 is implemented or derived – codefox Mar 22 '16 at 11:57
  • @codefox see my edit, from reflection point of view, C2 is always implementing I1, whether you reimplement it or not. – Martin Verjans Mar 22 '16 at 12:18
0

Since its not very clear what information exactly you are looking for, here are two approches:

First, you can use the Type.GetInterfaceMap Method to check if the type implements a method of the interface:

public static bool TypeImplementsInterfaceMethod(this Type t, Type interfaceType)
{
    if (t.IsInterface) return false;
    if (!t.GetInterfaces().Contains(interfaceType)) return false;
    return t.GetInterfaceMap(interfaceType).TargetMethods.Any(method => method.DeclaringType == t);
}

Second, you can check if another interface or the basetype already implements the interface:

public static bool TypeDirectlyImplementsInterface(this Type t, Type interfaceType)
{
    var interfaces = t.GetInterfaces();
    if (!interfaces.Contains(interfaceType)) return false;

    if (interfaces.Where(type => type != interfaceType)
            .SelectMany(type => type.GetInterfaces())
            .Contains(interfaceType))
        return false;

    if (t.BaseType == null) return true;
    return !t.BaseType.GetInterfaces().Contains(interfaceType);
}
thehennyy
  • 4,020
  • 1
  • 22
  • 31