介绍
在csharp中,CallerMemberName
, CallerFilePath
, 和 CallerLineNumber
是编译时常量,它们是csharp 5.0引入的特性,用于提供有关调用堆栈的信息,通常用于日志记录和调试。这些特性可以自动填充方法的参数,无需显式传递信息。
所属命名空间:
System.Runtime.CompilerServices
所属程序集:
System.Runtime.dll
CallerMemberName
定义
CallerMemberNameAttribute 类
允许获取方法调用方的方法或属性名称。
[System.AttributeUsage(System.AttributeTargets.Parameter, Inherited=false)]
public sealed class CallerFilePathAttribute : Attribute
作用
CallerMemberName
提供调用方成员的名称(方法或属性)。
使用效果
调用位置 | CallerMemberName获取的成员名称结果 |
---|---|
方法、属性或事件 | 方法,属性或事件的名称 |
构造函数 | 字符串 “.ctor” |
静态构造函数 | 字符串 “.cctor” |
析构函数 | 该字符串 “Finalize” |
用户定义的运算符或转换 | 生成的名称成员,例如, “op_Addition”。 |
特性构造函数 | 特性所应用的成员的名称 |
使用示例
定义一个方法加上一个默认参数,增加CallerMemberName
特性
public void Work([CallerMemberName] string memberName = ""){Console.WriteLine("CallerMemberName:" + memberName);}
在方法中调用:
void Playing(){Work();}
在构造函数中调用:
internal class Program{static void Main(string[] args){Console.WriteLine("Hello, World!");TestClass testClass = new TestClass();// testClass.Playing();Console.ReadKey();}}class TestClass{public TestClass(){Work();}public void Playing(){Work();}public void Work([CallerMemberName] string memberName = ""){Console.WriteLine("CallerMemberName:" + memberName);}}
CallerFilePath
定义
CallerFilePathAttribute 类
允许获取包含调用方的源文件的完整路径。 这是编译时的文件路径。
[System.AttributeUsage(System.AttributeTargets.Parameter, Inherited=false)]
public sealed class CallerFilePathAttribute : Attribute
作用
CallerFilePath
提供调用者的源文件路径。
使用示例:
定义一个方法加上一个默认参数,增加CallerFilePath
特性,调用时,会自动返回调用文件的完整路径
class TestClass{public void Playing(){Work();}public void Work([CallerFilePath] string filePath = ""){Console.WriteLine("CallerFilePath:" + filePath);}}
CallerLineNumber
定义
CallerLineNumberAttribute 类
允许获取源文件中调用方法的行号。
[System.AttributeUsage(System.AttributeTargets.Parameter, Inherited=false)]
public sealed class CallerLineNumberAttribute : Attribute
作用
CallerLineNumber
提供调用者的源文件中的行号。
使用场景
CallerMemberName
、 CallerFilePath
、CallerLineNumber
几个特性必须用于具有默认值的可选参数。 必须为可选参数指定显式默认值。 不能将特性用于未指定为可选的参数。
1.MVVM模式
在绑定数据时实现 INotifyPropertyChanged 接口。 此接口允许对象的属性通知绑定控件该属性已更改,以便此控件能够显示更新的信息。 如果没有 CallerMemberName
特性,则必须将属性名称指定为文本。
public class ViewModelBase : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;public void OnPropertyChanged([CallerMemberName]string propertyName = ""){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
如果不加[CallerMemberName]
,每次调用OnPropertyChanged
时,都要加上对应属性
加了[CallerMemberName]
,只需要直接调用OnPropertyChanged();
无需再一一传参数。
public class MainWindowViewModel : ViewModelBase{private string _name;private string _mySelectedItem;private string _status;public string Name{get{return _name;}set{_name = value;OnPropertyChanged();}}public string MySelectedItem{get{return _mySelectedItem;}set{_mySelectedItem = value;OnPropertyChanged();}}public string Status{get{return _status;}set{_status = value;OnPropertyChanged();}}}
2.日志
在日志记录中包含调用该方法的信息,用于调试和调用记录,创建一个打印日志的方法,加上上面这些标签,然后只要在需要打印的地方调用,即可打印,使用时把`。
public void Log(string message,[CallerMemberName] string memberName = "",[CallerFilePath] string sourceFilePath = "",[CallerLineNumber] int sourceLineNumber = 0){//打印日志Console.WriteLine("------------------------");Console.WriteLine("Message:" + message);Console.WriteLine("MemberName:" + memberName);Console.WriteLine("FilePath:" + sourceFilePath);Console.WriteLine("LineNumber:" + sourceLineNumber);Console.WriteLine("------------------------");}
完整代码示例:
internal class Program{static void Main(string[] args){TestClass testClass = new TestClass();testClass.Log("主函数执行开始");Console.WriteLine("Hello, World!");testClass.Playing();testClass.Log("主函数执行结束");Console.ReadKey();}}class TestClass{public void Playing(){Log("执行play");}public void Log(string message,[CallerMemberName] string memberName = "",[CallerFilePath] string sourceFilePath = "",[CallerLineNumber] int sourceLineNumber = 0){//打印日志Console.WriteLine("------------------------");Console.WriteLine("Message:" + message);Console.WriteLine("MemberName:" + memberName);Console.WriteLine("FilePath:" + sourceFilePath);Console.WriteLine("LineNumber:" + sourceLineNumber);Console.WriteLine("------------------------");}}
效果: