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.
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);
}
}
}
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
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.
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);
}
}
}
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.
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.
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
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
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.
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
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!
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
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)