介绍

在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特性

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

在方法中调用:

   void Playing()
   {
       Work();
   }

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

在构造函数中调用:

     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);
        }
    }

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

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);
      }
  }

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

CallerLineNumber

定义

CallerLineNumberAttribute 类

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

[System.AttributeUsage(System.AttributeTargets.Parameter, Inherited=false)]
public sealed class CallerLineNumberAttribute : Attribute

作用

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

使用场景

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

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时,都要加上对应属性

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

加了[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();
         }
     }

}

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

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("------------------------");
        }
    }

效果:

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

06-17 16:45