• C#的变迁史


    Caller Information

      CallerInformation是一个简单的新特性,包括三个新引入的Attribute,使用它们可以用来获取方法调用者的信息,

      这三个Attribute在System.Runtime.CompilerServices命名空间下,分别叫做CallerMemberNameAttribute,CallerFilePathAttribute和CallerLineNumberAttribute。

    CallerMemberNameAttribute:用来获取方法调用者的名称
    CallerFilePathAttribute:用来获取方法调用者的源代码文件路径
    CallerLineNumberAttribute:用来获取方法调用者所在的行号

      简单看一个小例子:

    using System;
    using System.Runtime.CompilerServices;
    
    class Program
    {
        static void Main(string[] args)
        {
            DoProcessing();
            Console.ReadKey();
        }
    
        static void DoProcessing()
        {
            TraceMessage("Something happened.");
        }
    
        static void TraceMessage(string message,
                [CallerMemberName] string memberName = "",
                [CallerFilePath] string sourceFilePath = "",
                [CallerLineNumber] int sourceLineNumber = 0)
        {
            Console.WriteLine("message: " + message);
            Console.WriteLine("member name: " + memberName);
            Console.WriteLine("source file path: " + sourceFilePath);
            Console.WriteLine("source line number: " + sourceLineNumber);
        }
    }

    不用多说了,结果很清楚。


      不过需要注意,Caller Info的这些Attribute只能用在optional parameter上,也就是说要指定默认值的。
      此外对于CallerMemberNameAttribute需要多说一点,使用这个Attribute可以避免在程序中硬编码调用方的函数名,至于这个属性返回的名字一般是这样的:

    调用方法的类型 获取的结果
    方法,属性,事件 方法,属性或事件的名字
    构造函数 字符串".ctor"
    静态构造函数 字符串".cctor"
    Finalize函数 字符串"Finalize"
    用户自定义的操作 编译产生的名字,比如"op_Addition"
    Attribute构造函数 应用此Attribute的成员函数名字。如果不是应用于成员的Attribute,比如说是应用于类型的Attribute,则使用其设置的默认值

      这个特性在WPF的MVVM模式中很有用。在WPF的MVVM设计模式中的viewmodel里,我们是用INotifyPropertyChanged接口去通知在viewmodel里的改变。具体实现中很多的Binding是通过字符串来标识的,当修改一个Property的名字的时候,有时候很可能会忘记更新通知中的字符串名字,使用这个新的CallerMemberNameAttribute就能避免这个问题。
      例如以前通常的一种实现是这样的:

    public class EmployeeVM:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
      
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
      
        private string _name;
      
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }  
    }

    这种实现中Property的名字"Name"是以字符串的形式来约定的,一旦这个Property被Rename后忘记改了此处,就会带来bug。使用新的Attribute以后就可以这么写了:

    public class EmployeeVM:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
      
        public void OnPropertyChanged([CallerMemberName] string propertyName=null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
      
        private string _name;
      
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
             OnPropertyChanged();
            }
        }
    }

    这么一来就不用硬编码了,简单。

  • 相关阅读:
    LeetCode题解——两数之和
    题解LeetCode——回文数
    汇编语言入门教程
    python基础--局部变量与全局变量
    linux--基础知识1
    python基础--函数
    字符串format函数使用
    字符串的拼接
    python基础--6 集合
    python基础--5字典
  • 原文地址:https://www.cnblogs.com/dxy1982/p/3668319.html
Copyright © 2020-2023  润新知