从 StackFrame 获取真实类型的泛型方法

Get real type of generic method from StackFrame

在我的日志记录模块中有一行:

MethodBase methodBase = new StackFrame(2, false).GetMethod();

我检查的方法是泛型方法,定义为T[] MyMethod<T>()。有没有办法从 methodBase 获取其真实类型而不是 T

使用 MethodBase 中的 GetGenericArguments 获取传入 T 的内容。

据我所知,你不能这样做。 StackFrame 中的信息不是从 运行 时间信息中检索的,而是从 .pdb 信息中检索的,将堆栈帧中找到的 return 地址与 .pdb 中描述的程序集偏移相关联。 PDB。 IE。只有编译时的信息,当然是开放的泛型方法。

请注意,即使您手动构造一个封闭的泛型方法并直接调用它,您仍然从 .pdb 中获取开放的泛型方法。例如:

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];
    }
}

在上面的示例中,最后分配的 type 变量值仍然引用开放泛型方法的 {T} 类型,而不是您所希望的 Int32 .尽管 Int32 类型 可从 miClosed 变量引用中检索的事实。

如果您需要特定的类型信息,则必须在代码中提供一种机制来明确确定它(例如,将 typeof(T) 的值从通用方法本身传递给日志记录组件)。 StackFrame class 没有必要的信息来为您做这件事。