[CallerMemberName] медленнее по сравнению с альтернативами при реализации INotifyPropertyChanged?

99

Есть хорошие статьи, предлагающие разные способы реализацииINotifyPropertyChanged .

Рассмотрим следующую базовую реализацию:

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
            }
        }
    }
}

Я бы хотел заменить его на этот:

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();
            }
        }
    }
}

Но иногда я читаю, что этот [CallerMemberName]атрибут работает хуже по сравнению с альтернативами. Это правда и почему? Использует ли отражение?

JYL
источник

Ответы:

201

Нет, использование [CallerMemberName]не медленнее, чем верхняя базовая реализация.

Это потому, что, согласно этой странице MSDN ,

Значения информации о вызывающем абоненте передаются в виде литералов на промежуточном языке (IL) во время компиляции.

Мы можем проверить это с помощью любого дизассемблера IL (например, ILSpy ): код для операции «SET» свойства компилируется точно так же: Декомпилированное свойство с CallerMemberName

Так что здесь не используется Reflection.

(образец составлен с помощью VS2013)

JYL
источник
2
Та же ссылка, но на английском вместо французского: msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx
Майк де Клерк
2
@MikedeKlerk Не уверен, почему вы не отредактировали его прямо в ответе, хотя сейчас я это сделал.
Ян Кемп