如何用nameof而不是魔术字符串实现INotifyPropertyChanged?

时间:2014-12-12 11:14:17

标签: c# mvvm inotifypropertychanged c#-6.0

我正在阅读C#6中新的nameof关键字。 我想知道如何使用此关键字实现INotifyPropertyChanged,哪些先决条件(当然除了C#6)以及它将如何影响我的MVVM应用程序的性能?

5 个答案:

答案 0 :(得分:9)

看起来像这样:

public string Foo
{
   get
   {
      return this.foo;
   }
   set
   {
       if (value != this.foo)
       {
          this.foo = value;
          OnPropertyChanged(nameof(Foo));
       }
   }
}

nameof(Foo)将替换为" Foo"字符串在编译时,所以它应该是非常高效的。这不是反思。

答案 1 :(得分:6)

这只是使用nameof()而不是魔术字符串的问题。以下示例来自我的blog article主题:

private string currentTime;

public string CurrentTime
{
    get
    {
        return this.currentTime;
    }
    set
    {
        this.currentTime = value;
        this.OnPropertyChanged(nameof(CurrentTime));
    }
}

由于它是evaluated at compile-time,因此它比任何当前替代品(博客文章中也提到)更具性能。

答案 2 :(得分:3)

这是使用新C#6.0糖的类的完整代码示例:

public class ServerViewModel : INotifyPropertyChanged {
    private string _server;
    public string Server {
        get { return _server; }
        set {
            _server = value;
            OnPropertyChanged(nameof(Server));
        }
    }

    private int _port;
    public int Port {
        get { return _port; }
        set {
            _port = value;
            OnPropertyChanged(nameof(Port));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) => 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

有了这个,你得到nameof()运算符,空条件运算符?.和表达式函数(OnPropertyChanged定义)。

答案 3 :(得分:3)

我发现使用PropertyChanged.Fody要容易得多,因为你最终会减少错误,而且代码会更加清晰,请参阅 - https://github.com/Fody/PropertyChanged

您所要做的就是使用ImplementPropertyChanged属性标记您的课程:

[ImplementPropertyChanged]
public class Person 
{        
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
}

在构建之后,它会转变为:

public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }

    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }

    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }

    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

答案 4 :(得分:0)

See the documentation for INotifyPropertyChanged.PropertyChanged Event

(defn fib [n]
  (if (< n 2)
    n
    (loop [i 1
           lst 0
           nxt 1]
      (if (>= i n)
        nxt
        (recur (inc i) nxt (+' lst nxt))))))