c# - 为什么 INotifyPropertyChanged 的​​ SetProperty() 方法需要一个 ref 参数?

标签 c# inotifypropertychanged ref

考虑到 INotifyPropertyChanged 的​​实现通常是这样的:

    public class Observable : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void SetProperty<T>(ref T storage, T value, [CallerMemberName]string propertyName = null)
        {
            if (Equals(storage, value))
            {
                return;
            }

            storage = value;
            OnPropertyChanged(propertyName);
        }

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

为什么 SetProperty 方法需要一个 ref 参数?除了类字段之外几乎没有任何其他东西被传递给方法,所以它应该始终是引用类型?

注意:我问这个问题是因为我想将此方法用于通过 foreach 循环枚举的项目,这不适用于 ref 关键字。

最佳答案

目的是通过引用传递一个字段,以及新值。

如果这不是 ref 参数,您将传递该字段的...此时此语句:

storage = value;

... 将毫无意义。这会改变参数的值,但根本不会修改字段

这里有一个完整的例子来展示差异:

using System;

class Program
{
    static string field;

    static void Main()
    {
        field = "initial value";
        Console.WriteLine($"Before Modify1: {field}");

        Modify1(field, "new value for Modify1");
        Console.WriteLine($"After Modify1: {field}");

        Modify2(ref field, "new value for Modify2");
        Console.WriteLine($"After Modify2: {field}");
    }

    static void Modify1(string storage, string value)
    {
        // This only changes the parameter
        storage = value; 
    }

    static void Modify2(ref string storage, string value)
    {
        // This changes the variable that's been passed by reference,
        // e.g. a field
        storage = value;
    }        
}

输出:

Before Modify1: initial value
After Modify1: initial value
After Modify2: new value for Modify2

如您所见,Modify1(没有 ref)根本没有修改字段,而 Modify2 做了。

关于c# - 为什么 INotifyPropertyChanged 的​​ SetProperty() 方法需要一个 ref 参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56134968/

相关文章:

c# - 为什么没有 char.IsUpper Invariant/char.IsLower Invariant 方法?

c# - JQuery 数据表在我的 Blazor 和 .NET Core 项目中不起作用

c# - 为什么 List<T> 属性的通知不起作用

c# - 公共(public)变量的传递地址

string - 在 Cloudformation YAML 中,在多行字符串中使用 Ref (?使用 Fn :Sub)

c# - 7 秒 EF 启动时间,即使对于微小的 DbContext

c# - 插入数据后如何刷新GridView?

c# - 如何正确使用DataBinding、INotifyPropertyChanged、ListViewGridView

wpf - 如何在WPF/XAML中正确使用INotifyPropertyChanged

c# - C# ref 的技术含义