Is it possible to reflect on an explicit interface implementation from the call stack? I want to use this info to look up an attribute on the interface itself.
Given this code:
interface IFoo
{
void Test();
}
class Foo : IFoo
{
void IFoo.Test() { Program.Trace(); }
}
class Program
{
static void Main(string[] args)
{
IFoo f = new Foo();
f.Test();
}
public static void Trace()
{
var method = new StackTrace(1, false).GetFrame(0).GetMethod();
// method.???
}
}
Specifically, in Trace(), I would like to be able to get to typeof(IFoo)
from method
.
In the watch window, if I look at method.ToString()
it gives me Void InterfaceReflection.IFoo.Test()
(InterfaceReflection is the name of my assembly).
How can I get to typeof(IFoo)
from there? Must I use a name-based type lookup from the assembly itself, or is there a Type IFoo
hidden somewhere in the MethodBase
?
UPDATE:
Here's the final solution, thanks to Kyte
public static void Trace()
{
var method = new StackTrace(1, false).GetFrame(0).GetMethod();
var parts = method.Name.Split('.');
var iname = parts[parts.Length - 2];
var itype = method.DeclaringType.GetInterface(iname);
}
itype
will have the interface type for the implementing method. This will only work with explicit interface implementations, but that's exactly what I need. Now I can use itype
to query attributes attached to the actual interface type.
Thanks to everyone for their help.
Testing around with VS2010, I found DeclaringType, which gets the object type that contains the method, from where you can get the interfaces as Type objects.
public static void Trace() {
var stack = new StackTrace(1, true);
var frame = stack.GetFrame(0);
var method = frame.GetMethod();
var type = method.DeclaringType;
Console.WriteLine(type);
foreach (var i in type.GetInterfaces()) {
Console.WriteLine(i);
}
}
Returns:
TestConsole.Foo
TestConsole.IFoo
(I called the project TestConsole)
method
will be a System.Reflection.RuntimeMethodInfo
, which is a class derived from System.Reflect.MethodBase
. You could e.g. call Invoke()
on it (though if you did so at the point where you obtained it, then this is going to result in an infinite recursion that eventually dies by overflowing the stack).
Calling ToString()
on it returns a fully qualified name. Did you call the project InterfaceReflection?
Not sure what more you want than that.
Edit: Okay, now I do. To find the declaring type look at the DeclaringType property, this will return the class on which the method was declared (which could be the class it was called on, or a base class):
So far so easy, this returns a Type object for Foo.
Now for the tricky bit, because you care about the interface it was declared on. However, there could be more than one interface that defined a method with precisely the same signature, which means the simple question "if this came from an interface, what was that interface?" doesn't always have a single answer.
There may be a neater way to do this, but all I can think of is calling GetInterfaces()
on the Type
object you got from DeclaringType
, and then looking for one whose name matches the method's signature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With