C#如何在构造函数中获取调用该构造函数的类名?
问题
现有C#代码如下,需要在MyObject的构造函数中获取调用该构造函数的类名,预期输出为Program,已知可以通过反射相关能力实现,需要明确具体实现方法。
public class Program { static void Main(string[] args) { MyObject object = new MyObject(); } } public class MyObject { public MyObject() { Console.WriteLine(GetCallerClass()); // 预期输出: 'Program' } }
注:示例代码中变量名object是C#内置关键字,直接写会编译报错,实际使用需要改名为其他合法标识符,或加@前缀写作@object。
实现方法
通过System.Diagnostics.StackTrace获取调用栈,结合反射读取栈帧对应的方法元数据就能拿到调用方类名,不需要其他特殊依赖。
完整可运行代码:
using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; public class Program { static void Main(string[] args) { MyObject obj = new MyObject(); // 控制台输出 Program } } public class MyObject { public MyObject() { Console.WriteLine(GetCallerClass()); } // 标记禁止内联,避免Release模式编译优化后栈帧偏移导致结果错误 [MethodImpl(MethodImplOptions.NoInlining)] private string GetCallerClass() { // 栈帧索引0是当前GetCallerClass方法,索引1是MyObject构造函数,索引2是调用构造函数的上层方法 StackFrame callerFrame = new StackTrace().GetFrame(2); MethodBase callerMethod = callerFrame.GetMethod(); // 方法的DeclaringType属性就是该方法所属的类 return callerMethod.DeclaringType.Name; } }
注意点
- 传入
GetFrame的索引需要根据你实际的调用层级调整:比如如果你不在构造函数里额外包一层GetCallerClass,而是直接在构造函数里写栈跟踪逻辑,那索引改成1即可。 - 栈跟踪+反射的方案有一定性能开销,不适合在高频调用的场景下使用。如果项目基于.NET 4.5及以上版本,优先用内置的调用方信息特性(
CallerMemberName、CallerFilePath等)实现,性能更好,也不会受编译优化影响。
内容的提问来源于stack exchange,提问作者Тимон Яблоков
相关产品推荐
相关产品推荐

