There are good articles that suggest different ways for implementing INotifyPropertyChanged
.
Consider the following basic implementation:
class BasicClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void FirePropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
private int sampleIntField;
public int SampleIntProperty
{
get { return sampleIntField; }
set
{
if (value != sampleIntField)
{
sampleIntField = value;
FirePropertyChanged("SampleIntProperty"); // ouch ! magic string here
}
}
}
}
I'd like to replace it with this one:
using System.Runtime.CompilerServices;
class BetterClass : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
// Check the attribute in the following line :
private void FirePropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
private int sampleIntField;
public int SampleIntProperty
{
get { return sampleIntField; }
set
{
if (value != sampleIntField)
{
sampleIntField = value;
// no "magic string" in the following line :
FirePropertyChanged();
}
}
}
}
But sometimes I read that the [CallerMemberName]
attribute has poor performances compared to alternatives. Is that true and why? Does it use reflection?
No, the use of [CallerMemberName]
is not slower than the upper basic implementation.
This is because, according to this MSDN page,
Caller Info values are emitted as literals into the Intermediate Language (IL) at compile time
We can check that with any IL disassembler (like ILSpy) : the code for the "SET" operation of the property is compiled exactly the same way :
So no use of Reflection here.
(sample compiled with VS2013)