In my logging module I have the line:
MethodBase methodBase = new StackFrame(2, false).GetMethod();
The method I inspect is a generic method and defined as T[] MyMethod<T>()
. Is there a way to get its real type instead of T
from methodBase
?
As far as I know, you can't do this. The information in the StackFrame
is retrieved not from run-time information, but from the .pdb information, correlating the return address found in the stack frame with the assembly offsets described in the .pdb. I.e. only the compile-time information is available, which of course is the open generic method.
Note that even if you manually construct a closed generic method and invoke it directly, you still get the open generic method from the .pdb. For example:
class Program
{
static void Main(string[] args)
{
MethodInfo miOpen = typeof(Program).GetMethod("Method", BindingFlags.Static | BindingFlags.NonPublic),
miClosed = miOpen.MakeGenericMethod(typeof(int));
Type type;
object[] invokeArgs = { 17, null };
int[] rgi = (int[])miClosed.Invoke(null, invokeArgs);
type = (Type)invokeArgs[1];
}
static T[] Method<T>(T t, out Type type)
{
type = GetMethodType();
return new[] { t };
}
private static Type GetMethodType()
{
StackFrame frame = new StackFrame(1, false);
MethodBase mi = frame.GetMethod();
return mi.GetGenericArguments()[0];
}
}
In the above example, the type
variable value assigned at the end still references the {T}
type for the open generic method, not Int32
as you would hope in your case. This, in spite of the fact that the Int32
type is retrievable from the miClosed
variable reference.
If you want the specific type information, you will have to provide a mechanism in your code to determine it explicitly (e.g. pass the value of typeof(T)
to the logging component from the generic method itself). The StackFrame
class doesn't have the necessary information to do that for you.
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