ViewModelBase的构建以及为什么要使用[CallerMemberName] string propertyName = null

发布于:2025-06-06 ⋅ 阅读:(18) ⋅ 点赞:(0)
 public class ViewModelBase : INotifyPropertyChanged
 {
     public event PropertyChangedEventHandler PropertyChanged;
     public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
     {
         PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
     }
 }

[CallerMemberName] string propertyName = null 是 C# 的一个特性(Attribute),它的作用是 自动获取调用该方法的方法或属性的名称,并将其作为 propertyName 参数传递进来。

具体作用:

  1. 简化 OnPropertyChanged 调用
    在 INotifyPropertyChanged 的实现中,通常需要在属性 setter 里触发 PropertyChanged 事件,并传入属性名。例如:

    private string _name;
    public string Name
    {
        get => _name;
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");  // 需要手动传入属性名
            }
        }
    }

    使用 [CallerMemberName] 后,可以省略参数,编译器会自动填充:

    OnPropertyChanged();  // 编译器会自动填充 "Name" 作为参数

  2. 避免硬编码属性名
    传统方式需要手动传入字符串,容易因拼写错误导致 bug,而 [CallerMemberName] 让编译器自动获取属性名,更安全。

  3. 适用于任何调用者
    不仅限于属性,如果是方法调用,[CallerMemberName] 也会自动获取方法名。

完整示例:

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

public class MyViewModel : ViewModelBase
{
    private int _age;
    public int Age
    {
        get => _age;
        set
        {
            if (_age != value)
            {
                _age = value;
                OnPropertyChanged();  // 自动填充 "Age" 作为参数
            }
        }
    }
}