C#特性-CallerMemberName、CallerFilePath和CallerLineNumber的介绍和应用

介绍

在csharp中,CallerMemberName, CallerFilePath, 和 CallerLineNumber 是编译时常量,它们是csharp 5.0引入的特性,用于提供有关调用堆栈的信息,通常用于日志记录和调试。这些特性可以自动填充方法的参数,无需显式传递信息。

所属命名空间:

System.Runtime.CompilerServices

所属程序集:

System.Runtime.dll

CallerMemberName

定义

CallerMemberNameAttribute 类

允许获取方法调用方的方法或属性名称。

csharp 复制代码
[System.AttributeUsage(System.AttributeTargets.Parameter, Inherited=false)]
public sealed class CallerFilePathAttribute : Attribute

作用

CallerMemberName 提供调用方成员的名称(方法或属性)。

使用效果

调用位置 CallerMemberName获取的成员名称结果
方法、属性或事件 方法,属性或事件的名称
构造函数 字符串 ".ctor"
静态构造函数 字符串 ".cctor"
析构函数 该字符串 "Finalize"
用户定义的运算符或转换 生成的名称成员,例如, "op_Addition"。
特性构造函数 特性所应用的成员的名称

使用示例

定义一个方法加上一个默认参数,增加CallerMemberName特性

csharp 复制代码
 public void Work([CallerMemberName] string memberName = "")
 {
     Console.WriteLine("CallerMemberName:" + memberName);
 }

在方法中调用:

csharp 复制代码
   void Playing()
   {
       Work();
   }

在构造函数中调用:

csharp 复制代码
     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 类

允许获取包含调用方的源文件的完整路径。 这是编译时的文件路径。

csharp 复制代码
[System.AttributeUsage(System.AttributeTargets.Parameter, Inherited=false)]
public sealed class CallerFilePathAttribute : Attribute

作用

CallerFilePath 提供调用者的源文件路径。

使用示例:

定义一个方法加上一个默认参数,增加CallerFilePath 特性,调用时,会自动返回调用文件的完整路径

csharp 复制代码
  class TestClass
  {
      public void Playing()
      {
          Work();
      }

      public void Work([CallerFilePath] string filePath = "")
      {
          Console.WriteLine("CallerFilePath:" + filePath);
      }
  }

CallerLineNumber

定义

CallerLineNumberAttribute 类

允许获取源文件中调用方法的行号。

csharp 复制代码
[System.AttributeUsage(System.AttributeTargets.Parameter, Inherited=false)]
public sealed class CallerLineNumberAttribute : Attribute

作用

CallerLineNumber 提供调用者的源文件中的行号。

使用场景

CallerMemberNameCallerFilePathCallerLineNumber几个特性必须用于具有默认值的可选参数。 必须为可选参数指定显式默认值。 不能将特性用于未指定为可选的参数。

1.MVVM模式

在绑定数据时实现 INotifyPropertyChanged 接口。 此接口允许对象的属性通知绑定控件该属性已更改,以便此控件能够显示更新的信息。 如果没有 CallerMemberName 特性,则必须将属性名称指定为文本。

csharp 复制代码
public class ViewModelBase : INotifyPropertyChanged
  {
      public event PropertyChangedEventHandler PropertyChanged;

      public void OnPropertyChanged([CallerMemberName]string propertyName = "")
      {
          PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
      }
  }
  
  

如果不加[CallerMemberName],每次调用OnPropertyChanged时,都要加上对应属性

加了[CallerMemberName],只需要直接调用OnPropertyChanged();无需再一一传参数。

csharp 复制代码
 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.日志

在日志记录中包含调用该方法的信息,用于调试和调用记录,创建一个打印日志的方法,加上上面这些标签,然后只要在需要打印的地方调用,即可打印,使用时把`。

csharp 复制代码
       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("------------------------");
       }

完整代码示例:

csharp 复制代码
    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("------------------------");
        }
    }

效果:

相关推荐
csbysj20206 分钟前
Java 条件语句
开发语言
宝桥南山35 分钟前
GitHub Models - 尝试一下使用GitHub Models
microsoft·ai·微软·c#·github·.netcore
Ulyanov42 分钟前
《现代 Python 桌面应用架构实战:PySide6 + QML 从入门到工程化》 开发环境搭建与工具链极简主义 —— 拒绝臃肿,构建工业级基座
开发语言·python·qt·ui·架构·系统仿真
逻辑驱动的ken1 小时前
Java高频面试场景题19
java·开发语言·面试·职场和发展·求职招聘
初心未改HD1 小时前
Go语言net/http与Web开发:构建高性能HTTP服务
开发语言·golang
叼烟扛炮1 小时前
C++第一讲:C++ 入门基础
开发语言·c++·函数重载·引用·内联函数·nullptr
Ulyanov2 小时前
《现代 Python 桌面应用架构实战:PySide6 + QML 从入门到工程化》:QML 声明式语法与霓虹按钮 —— 当 Python 遇见现代美学
开发语言·python·ui·qml·系统仿真·雷达电子对抗仿真
弹不出的5h3ll2 小时前
Ghost Bits:高位截断如何让 Java WAF 形同虚设
java·开发语言
码界筑梦坊2 小时前
113-基于Python的国际超市电商销售数据可视化分析系统
开发语言·python·信息可视化·毕业设计·fastapi
memories1982 小时前
Go 语言 Channel(管道/通道)
开发语言·后端·golang