从StackFrame中获取真正的泛型方法

Den*_*nis 7 c# reflection

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

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

我检查的方法是一种通用方法,定义为T[] MyMethod<T>().有没有办法得到它的实型,而不是TmethodBase

Pet*_*iho 5

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

请注意,即使您手动构造一个封闭的泛型方法并直接调用它,您仍然可以从 .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];
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,最后type分配的变量值仍然引用{T}了开放泛型方法的类型,而不是Int32你所希望的。尽管可以从变量引用中检索该Int32类型,但仍然如此。miClosed

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