【问题标题】:MVVM CallerMemberName and "magic strings"MVVM CallerMemberName 和“魔术字符串”
【发布时间】:2025-12-05 03:15:02
【问题描述】:

新的 C# 5.0 版本引入了一些东西来摆脱 INotifyPropertyChanged 实现中的“魔术字符串”,例如:

OnPropertyChanged("CustomerName");

现在可以只写:

OnPropertyChanged();

这可能是由于方法定义中的 CallerMemberName:

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{ ... }

它比“魔术字符串”方式更易于重构,并且比 lambda 表达式更快,但我想知道我们如何从一组访问器中多次调用 OnPropertyChanged。例如,如果我们想要这样的东西:

public int Width
{
    get
    {
        return width;
    }
    set
    {
        width = value;
        OnPropertyChanged("Width");
        OnPropertyChanged("Height");
    }
}

我们如何使用 CallerMemberName 方式做到这一点,并避免使用“魔术字符串”和 lambda 表达式?

我也想知道如何避免在 IDataError 信息中使用“魔术字符串”:

public string Error
        {
            get;
            private set;
        }

        public string this[string columnName]
        {
            get
            {
                if (columnName == "Name")
                {
                    if (String.IsNullOrWhiteSpace(Name))
                        Error = "Name cannot be null or empty.";
                    else
                        Error = null;
                }

                return Error;
            }
        }

我是 MVVM 的新手,所以也许我忽略了一些处理“魔术字符串”的巧妙方法,但是我做了一些研究,却一无所获。

【问题讨论】:

  • 为什么只因为宽度变了就说高度变了呢?你的意思是像“Size”这样的东西吗?
  • 这只是一个例子,但有时一个属性可能依赖于另一个。例如,如果宽度总是高度*2。

标签: c# mvvm inotifypropertychanged idataerrorinfo callermembername


【解决方案1】:

简单的答案是,你不能这样做。正如名称CallerMemberName 所示,它将包含调用者的姓名。
对于您想为当前的其他人提出PropertyChanged 的情况,您将不得不使用其中一种“旧”方式。

IDataErrorInfo你也必须使用其中一种方式,没有其他选择。

【讨论】:

    【解决方案2】:

    这将有助于: “某种魔法” 轻松 INotifyPropertyChanged

    http://visualstudiogallery.msdn.microsoft.com/d5cd6aa1-57a5-4aaa-a2be-969c6db7f88a

    作为将其添加到一个属性的示例:

    [Magic] 
    public string Name { get { return _name; } set { _name = value; } } 
    string _name;
    

    将它添加到所有类属性的另一个示例:

    [Magic] 
    public class MyViewModel: INotifyPropertyChanged 
    { 
      public string Name { get; set; } 
      public string LastName { get; set; } 
      ..... 
    }
    

    【讨论】:

    • -1;这可能是一个不错的工具,但我认为它不是解决 OPs 问题的方法。如果我弄错了,请通过一些解释改进您的答案。
    【解决方案3】:

    我知道这个问题是关于 C# 5.0 的,但是如果人们仍然有这个性质的问题,请查看 c# 6.0。 C# 6.0 有一个很好的方法来解决这个问题。查看 nameof 关键字。如果有人感兴趣,我写了一篇关于它的小帖子:c# 6.0 solves magic strings problem

    【讨论】: