1

使用 MVVM,我总是看到这两种属性方法:

    private int myProperty;
    public int MyProperty
    {
        get { return myProperty; }
        set
        {
            myProperty = value;
            NotifyPropertyChanged("MyProperty");
        }
    }

    private int myProperty;
    public int MyProperty
    {
        get { return myProperty; }
        set
        {
            myProperty = value;
            NotifyPropertyChanged(m => m.MyProperty);
        }
    }

第一个对 NotifyPropertyChanged 使用硬编码字符串,第二个对 NotifyPropertyChanged 使用 lambda 表达式。我不想发起辩论来询问什么是更好的解决方案,但我想了解这两种解决方案之间的区别。使用其中一种会有什么后果?

如果我错了,请纠正我,但 lambda 表达式解决方案应该使用更多内存并且应该比硬编码字符串慢,因为基类的 NotifyPropertyChanged 方法使用委托和反射。但是硬编码的字符串解决方案可能会产生愚蠢的错误,因为它是一个字符串,没有什么可以告诉我我正确地写了它。

4

3 回答 3

3

第二个表达式会在属性名称更改时生成编译器错误,或者会自动更改(通过 VS 或 ReSharper 中的重命名支持)。

所以基本上,您获得了对属性名称的编译器支持。提供给通知的错误名称将意味着数据绑定会中断。使用字符串名称,这种破坏将是无声的。

在我看来,在小型 UI 中选择无关紧要,但在具有沉重 UI 层的大型应用程序中,从长远来看,对错误的额外支持可以带来回报。

性能不会有问题地变慢,不要忘记,绑定无论如何都是反射驱动的。与往常一样,性能是相对的。硬编码版本在技术上会更快,因为它不需要从元数据中反映属性名称。快多少,我不确定。

于 2012-07-17T12:35:12.963 回答
1

而不是为每个属性重复 NotifyPropertyChanged 的​​代码,我觉得下面的代码更干净

在您的 ViewModel Base 中创建一个 Set 方法

protected bool Set<T>(Expression<Func<T>> selectorExpression, ref T field, T value)
{
    if (EqualityComparer<T>.Default.Equals(field, value))
       return false;
    field = value;
    RaisePropertyChanged(selectorExpression);
    return true;
}

并将它们用作

string title;
public string Title
{
   get { return title; }
   set { Set(() => Title, ref title, value); }
}
于 2012-07-17T13:05:00.300 回答
0

我在实现 INotifyPropertyChanged 的​​基类中使用了以下方法,它非常简单方便:

public void NotifyPropertyChanged()
    {
        StackTrace stackTrace = new StackTrace();

        MethodBase method = stackTrace.GetFrame(1).GetMethod();

        if (!(method.Name.StartsWith("get_") || method.Name.StartsWith("set_")))
        {
            throw new InvalidOperationException("The NotifyPropertyChanged() method can only be used from inside a property");
        }

        string propertyName = method.Name.Substring(4);

        RaisePropertyChanged(propertyName);
    }
于 2012-08-30T01:05:04.407 回答