从StackFrame获取Type T.

目标是基于调用my方法的类型创建一个通用实例。

问题是,当从generics调用时,StackFrame似乎只包含开放定义类型参数而不是封闭定义类型参数。 如何从StackFrame获取类型参数? 与此问题类似。 我想我的情况是不同的,因为Log.Debug是从一个封闭的方法调用的。

如果StackFrame不是正确的方法,除IoC以外的任何建议? 此代码用于填写对我的Unity容器的引用不可用的情况。

using System; using System.Reflection; namespace ReflectionTest { public class Logger { private readonly string loggerName; protected Logger(string loggerName) { this.loggerName = loggerName; } public void Debug(string message) { Console.WriteLine(string.Format("{0} - {1}", loggerName, message)); } } public class Logger : Logger { public Logger() : base(typeof(T).FullName) { } } public static class Log { public static void Debug(string message) { // Determine the calling function, and create a Logger for it. System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1); MethodBase method = frame.GetMethod(); /// When method is from a generic class, /// the method.ReflectedType definintion is open: Type.ContainsGenericParameters is true /// How do I get the generic parameters of method.ReflectedType so /// Activator.CreateInstance() will not throw? Type logType = typeof(Logger); Type constructed = logType.MakeGenericType(new Type[] { method.ReflectedType }); Logger logger = (Logger)Activator.CreateInstance(constructed); logger.Debug(message); } } public class MyBase { public void Run() { Log.Debug("Run Generic"); // throws on Activator.CreateInstance() } } class Program { static void Works() { Log.Debug("Run NonGeneric"); // works } static void DoesNotWork() { MyBase b = new MyBase(); b.Run(); } static void Main(string[] args) { Works(); DoesNotWork(); } } } 

堆栈帧不可靠,仅用于调试目的。 你不能假设有任何有用的东西。 这就是它在“诊断”命名空间中的原因。

但更一般地说,您的问题表明对堆栈框架告诉您的内容存在根本性的误解。 你说

目标是基于调用my方法的类型创建一个通用实例。

堆栈框架实际上并没有告诉您谁调用了您的方法 。 堆栈框架告诉您控件将返回的位置堆栈框架是延续的具体化谁打电话给方法以及控制将返回哪里几乎总是一样的事实是你混乱的根源,但我向你保证他们不必是一样的。

特别是,预览版中即将出现的“异步/等待”functioncertificate了这一点。 从await恢复的代码在堆栈框架上没有关于谁最初调用它的线索; 这些信息永远丢失了。 由于下一个要运行 的代码在逻辑上与最初调用该方法的代码分离,因此堆栈帧不包含该信息。

我们不需要像那样充满异国情调。 例如,假设方法M包含对方法N的调用,并且N调用方法O.如果抖动选择在M内部内联N,则从O观察到的堆栈帧将不包含N.堆栈帧告诉您控制何处当前方法返回时恢复。 当O返回时,控制将在M内恢复,而不是N,因此堆栈帧不包含关于N的任何信息。