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

时间:2015-01-02 00:11:00

标签: c# reflection

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

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

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

2 个答案:

答案 0 :(得分:4)

据我所知,你不能这样做。 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];
    }
}

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

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

答案 1 :(得分:-1)

使用GetGenericArguments之外的MethodBase来获取传递给T的内容。