O [CallerMemberName] é lento em comparação com as alternativas ao implementar INotifyPropertyChanged?

98

Existem bons artigos que sugerem diferentes formas de implementaçãoINotifyPropertyChanged .

Considere a seguinte implementação básica:

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

Eu gostaria de substituí-lo por este:

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

Mas às vezes eu li que o [CallerMemberName]atributo tem um desempenho ruim em comparação com as alternativas. Isso é verdade e por quê? Ele usa reflexão?

JYL
fonte

Respostas:

200

Não, o uso de [CallerMemberName]não é mais lento do que a implementação básica superior.

Isso ocorre porque, de acordo com esta página do MSDN ,

Os valores de informações do chamador são emitidos como literais na Linguagem Intermediária (IL) em tempo de compilação

Podemos verificar isso com qualquer desmontador IL (como ILSpy ): o código para a operação "SET" da propriedade é compilado exatamente da mesma maneira: Propriedade descompilada com CallerMemberName

Portanto, não há uso de reflexão aqui.

(amostra compilada com VS2013)

JYL
fonte
2
O mesmo link, mas em inglês em vez de francês: msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx
Mike de Klerk
2
@MikedeKlerk Não tenho certeza por que você não editou diretamente na resposta, embora eu já tenha feito isso.
Ian Kemp