如何通用获取当前类名称?C#日志场景下的实现疑问
解决日志中通用引用当前类名的问题
首先明确为什么你尝试的方法不行:
nameof(this)报错是因为nameof操作符只能接收标识符(类名、方法名、变量名等有明确名称的代码符号),而this是代表当前实例的表达式,不属于标识符范畴,因此编译器抛出CS8081错误。this.GetType()的问题在于,它是运行时获取实例的实际类型,如果当前类被继承,子类实例调用时会返回子类的类型名,而非代码所在的基类名;另外它是运行时求值,和nameof的编译时确定特性不一致。
下面是几种简洁通用的实现方式:
方式一:类内定义常量存储类名
在每个类中定义一个常量字段,用nameof(当前类)赋值,后续日志中直接引用这个常量。代码迁移时,IDE的重命名功能会自动更新nameof中的类名,无需手动修改每个日志引用:
class Class_Name { private const string _className = nameof(Class_Name); ICommand Command_Name => new RelayCommand(() => { var provenance = $"{_className}.{nameof(Command_Name)}"; // 执行日志记录 }); void Method_Name() { var provenance = $"{_className}.{nameof(Method_Name)}"; // 执行日志记录 } }
方式二:直接使用typeof(当前类).Name
typeof(当前类)是编译时确定的类型,其Name属性会返回类的名称,IDE重命名类时也会自动更新typeof中的类名,效果和nameof(当前类)一致,写法更紧凑:
class Class_Name { ICommand Command_Name => new RelayCommand(() => { var provenance = $"{typeof(Class_Name).Name}.{nameof(Command_Name)}"; // 执行日志记录 }); void Method_Name() { var provenance = $"{typeof(Class_Name).Name}.{nameof(Method_Name)}"; // 执行日志记录 } }
方式三:基类封装(适用于多类复用场景)
如果你的项目中有多个类需要这个功能,可以定义一个基类,封装获取当前类名的逻辑。注意如果需要获取代码所在类的名称(而非实例的实际类型),基类中需用typeof(当前基类),子类中则用typeof(子类):
public class BaseLoggable { protected string GetClassName() => typeof(BaseLoggable).Name; } class Class_Name : BaseLoggable { ICommand Command_Name => new RelayCommand(() => { var provenance = $"{typeof(Class_Name).Name}.{nameof(Command_Name)}"; // 若需获取实例实际类型,可改用 GetType().Name // var provenance = $"{GetType().Name}.{nameof(Command_Name)}"; }); }
内容的提问来源于stack exchange,提问作者Denis G. Labrecque
相关产品推荐
相关产品推荐

