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

标签 c# reflection

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

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

我检查的方法是泛型方法,定义为T[] MyMethod<T>() .有没有办法得到它的真实类型而不是 T来自 methodBase

最佳答案

据我所知,你不能这样做。 StackFrame 中的信息不是从运行时信息中检索的,而是从 .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变量值仍然引用了open泛型方法的{T}类型,而不是Int32 正如您所希望的那样。尽管可以从 miClosed 变量引用中检索到 Int32 类型

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

关于c# - 从 StackFrame 获取真实类型的泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27735949/

相关文章:

c# - 两个字符串特殊连接的更好方法

c# - 在 DataGridView 垂直滚动条上绘制标记

c# - 在运行时更改 LINQ-to-SQL 连接字符串

c# - 查明一个类型是否被引用,因此可能会在某个时间点被加载

.net - 如何使用反射判断类/方法是否可访问?

c# - 无法从程序集 xxx 加载类型 xxx

java - 反射性地获取与特定 url 匹配的 Spring MVC Controller 列表

c# - XMLReader 未知

c# - IServiceProvider.GetService(Type serviceType) 的目的是什么?

java - 使用java反射覆盖复杂对象实例中的值