从 StackFrame 获取真正类型的泛型方法 [英] Get real type of generic method from StackFrame

查看:37
本文介绍了从 StackFrame 获取真正类型的泛型方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In my logging module I have the line:

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

我检查的方法是一个通用方法,定义为T[] MyMethod().有没有办法从 methodBase 获取它的真实类型而不是 T?

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?

推荐答案

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

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.

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

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

在上面的例子中,最后分配的type变量值仍然引用了开放泛型方法的{T}类型,而不是Int32代码> 正如您希望的那样.尽管事实上 Int32 类型 可以从 miClosed 变量引用中检索.

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.

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

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.

这篇关于从 StackFrame 获取真正类型的泛型方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆