Use Reflection to find Methods that implement explicit interfaces - ISerializable - Roy Osherove's Blog

Use Reflection to find Methods that implement explicit interfaces

update: added a check for IsPrivate based on the comments.

so I won't forget: here's how you can iterate over a type definition's methods and see if one of them is an explicit intreface definition:

 

foreach (var info in GetType().GetMethods(
         BindingFlags.NonPublic|BindingFlags.Instance|BindingFlags.DeclaredOnly))
  {
   if (info.IsFinal && info.IsPrivate)
   {
         Console.WriteLine("Explicit interface implementation: {0}", info.Name);
   }
  }

 

this will show only the "Write" method for the following class:

public class Class1 : ILogger
{
public void show()
{
} 
void MyMethod()
{
}
void ILogger.Write(string s)
{
}
}
Published Wednesday, October 15, 2008 9:11 AM by RoyOsherove
Filed under:

Comments

Wednesday, October 15, 2008 9:55 AM by Bill McCarthy

# re: Use Reflection to find Methods that implement explicit interfaces

Try that on B.

Class A

  Protected Overridable Sub Foo()

  End Sub

End Class

Class B : Inherits A

  Protected NotOverridable Overrides Sub Foo()

  End Sub

End Class

You need to be looking at the interface mapping if you really want to be certain.

Wednesday, October 15, 2008 12:55 PM by Mihailo

# re: Use Reflection to find Methods that implement explicit interfaces

Bill is right, you can't use the code you've shown above, you have to use interface mapping.

Your code will show any sealed private method declared by the class.

You have to call Type's FindInterfaces method. Using interfaces you have to call GetInterfaceMap on each of the retrieved interfaces, and then check if the method that is implementing interface is private. Pretty simple :)

so something like this:

foreach (var anInterface in GetType().FindInterfaces()){

  var mapp = GetType().GetInterfaceMap(anInterface);

  foreach(var info in mapp.TargetMethods){

       if (info.IsPrivate)

       {

        Console.WriteLine("Explicit interface implementation: {0}", info.Name);

       }

  }

}

Wednesday, October 15, 2008 4:31 PM by Avish

# re: Use Reflection to find Methods that implement explicit interfaces

I can't shake the feeling that this can go wrong in some situations, or that it's only coincidentally correct. If I had to find explicit implementations, I'd go with something like this:

def FindExplicitImplementations(type as Type):

for interfaceType in type.GetInterfaces():

for method in type.GetInterfaceMap(interfaceType).TargetMethods:

yield method unless method.IsPublic

Wednesday, October 15, 2008 4:37 PM by RoyOsherove

# re: Use Reflection to find Methods that implement explicit interfaces

Mihailo: There is no such thing as a private sealed method that you can create manually - it will not compile (method has to override another method in order to be able to be sealed)

Also: Calling "GetInterfaceMap" when the interface is not explicitly used in the class - throws an exception.

Wednesday, October 15, 2008 5:27 PM by Mihailo

# re: Use Reflection to find Methods that implement explicit interfaces

Hi Roy,

a) you're right, I wanted to concur with Bill, sorry to lead you wrong way.

b) what do you mean by that?

I used this code, and it worked fine, try copy paste and see if it works for you:

foreach (var anInterface in typeof(Class1).FindInterfaces((type,criteria)=> true, ""))

           {

               var mapp = typeof(Class1).GetInterfaceMap(anInterface);

               foreach (var info in mapp.TargetMethods)

               {

                   if (info.IsPrivate)

                   {

                       Console.WriteLine("Explicit interface implementation: {0}", info.Name);

                   }

               }

           }

Wednesday, October 15, 2008 5:28 PM by Patrik Hägne

# re: Use Reflection to find Methods that implement explicit interfaces

Explicit interface implementations aren't necessarily private unless the language is C#. In VB for example all interface implementations are explicit and can have any scope. So if you're not sure that the class you're reflecting on is written in C# as far as I can see.

Thursday, October 16, 2008 9:28 AM by Dew Drop - October 16, 2008 | Alvin Ashcraft's Morning Dew

# Dew Drop - October 16, 2008 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop - October 16, 2008 | Alvin Ashcraft's Morning Dew

Thursday, October 16, 2008 9:19 PM by Bill McCarthy

# re: Use Reflection to find Methods that implement explicit interfaces

This code is still only useful for C#. With VB the  interface implementation can be explicitly mapped to public members with different names.

As I said earlier, the correct way is to use GetInterfaceMap.  I have not seen that throw exceptions for C#'s implicit implementation. Can you post an example of when it throws an exception ?  thanks.

Friday, October 17, 2008 2:29 AM by Arjan`s World » LINKBLOG for October 16, 2008

# Arjan`s World » LINKBLOG for October 16, 2008

Pingback from  Arjan`s World    » LINKBLOG for October 16, 2008

Friday, October 17, 2008 7:16 AM by Mihailo

# re: Use Reflection to find Methods that implement explicit interfaces

Hi Roy,

Did you get the code I've sent you? The first comment had a general idea how to do it, for the second one I actually wrote a console application to test your scenario, but I don't see my second comment in the list.

Cheers,

Mihailo

Friday, October 17, 2008 7:48 AM by RoyOsherove

# re: Use Reflection to find Methods that implement explicit interfaces

This solution works for VB.NET and C# code

Bill: yes this will also work on VB.NET since in VB.NET to make an EXPLICIT interface implementation, you need to make the method private (so that only casting to the interface shows it)

for example the following private method :

Private Sub Write(ByVal input As String) Implements ILogger.Write

   End Sub

Friday, October 17, 2008 7:49 AM by RoyOsherove

# re: Use Reflection to find Methods that implement explicit interfaces

Mihailo: you are right: I could not recreate that exception so your solution works as well. however, it has a loop within a loop so I'm not sure if it is as simple as mine is.

Friday, October 17, 2008 5:52 PM by Patrik Hägne

# re: Use Reflection to find Methods that implement explicit interfaces

All interface implementations in VB are explicit, Private, Protected, Friend and Public alike. Take the following class "SomeClass" where a public method explicitly implements two interface methods as an example. Your method would not find this.

Public Interface ISomeInterface

   Function Foo() As String

   Function Bar() As String

End Interface

Public Class SomeClass

   Implements ISomeInterface

   Public Overrides Function ToString() As String Implements ISomeInterface.Foo, ISomeInterface.Bar

       Return "Hello world!"

   End Function

End Class

Saturday, October 18, 2008 11:02 PM by Bill McCarthy

# re: Use Reflection to find Methods that implement explicit interfaces

Roy,

In VB today *All* interface implementation is Explicit.  I could have:

Public Sub Close() Implements IDisposable.Dispose()

Or I could make that Protected or Private.   In all cases with VB you can call the method directly from in the same type.  C# on the other hand forces a naming pattern on their interface mapping that forces you to cast to the interface because the method name is illegal to call form the C# compiler.  Once you have the method info though you can always invoke.

I think the problem here is what you are calling "explicit".  I think I discussed this with you before, there's really only two types of interface implementation as far as IL and the CLR are concerned, mapped or implicit.  VB doesn't at present have the implicit but it does have the full mapping as the CLR sets out.  C# on the other hand has implicit but only limited mapping.

I'm guessing the confusion here is this arbitrary definition of what you are calling "explicit" is a C# implementation thing only, not a CLR or a VB requirement.  As there are only two kinds of implementation at CLR level, when you say "explicit" that to me means you mean the other one than "implicit".  But it seems you mean something else ?

Monday, October 20, 2008 5:00 AM by RoyOsherove

# re: Use Reflection to find Methods that implement explicit interfaces

Bill: Nope, I think you're right and I misunderstood the "Explicit" and thought that VB had that same feature in its compiler when in fact it's even more powerful in terms of mapping.

That's pretty cool. I learned something!

Monday, October 20, 2008 12:26 PM by Bill McCarthy

# re: Use Reflection to find Methods that implement explicit interfaces

Thanks Roy :)  It's not that common for VB to actually have a more complete CLR implementation than C#, although it does in a few places such as custom Events have the Raise (or fire block) and optional parameters, but usually people think it's C# defines the CLR or is the complete implementation.  IL/CLR is actually more powerful than the two, jsut a real pain to write <g>

BTW: if this is for test code spits, I'd rather have the tests spit out a test of an interface (ideally, where possible re-use standard tests for that interface and treat NotSupported exceptions as a pass)