Considering the implementation of INotifyPropertyChanged usually looks like this :
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));
}
Why does the SetProperty
method need a ref argument ? There's hardly any chance that anything else than a class field gets passed to the method, so it should alway be a reference type anyway ?
Note : I ask this question because I want to use this method with items enumerated through a foreach
loop, which doesn't work with ref
keyword.
The intention is that you pass a field by reference, as well as the new value.
If this weren't a ref
parameter, you'd be passing the value of the field... at which point this statement:
storage = value;
... would be pointless. That would change the value of the parameter, but wouldn't modify the field at all.
Here's a complete example to demonstrate the difference:
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;
}
}
Output:
Before Modify1: initial value
After Modify1: initial value
After Modify2: new value for Modify2
As you can see, Modify1
(without ref
) didn't modify the field at all, whereas Modify2
did.