在我的记录模块中,我有一行:
MethodBase methodBase = new StackFrame(2, false).GetMethod();
我检查的方法是一种通用方法,定义为T[] MyMethod<T>()
。有没有办法从T
获取真实类型而不是methodBase
?
答案 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
的内容。