[CallerMemberName] è lento rispetto alle alternative durante l'implementazione di INotifyPropertyChanged?


98

Ci sono buoni articoli che suggeriscono diversi modi per l'implementazioneINotifyPropertyChanged .

Considera la seguente implementazione di base:

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

Vorrei sostituirlo con questo:

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

Ma a volte leggo che l' [CallerMemberName]attributo ha prestazioni scadenti rispetto alle alternative. È vero e perché? Usa la riflessione?

Risposte:


200

No, l'uso di [CallerMemberName]non è più lento dell'implementazione di base superiore.

Questo perché, secondo questa pagina MSDN ,

I valori delle informazioni sul chiamante vengono emessi come valori letterali nell'intermediate Language (IL) in fase di compilazione

Possiamo verificarlo con qualsiasi disassemblatore IL (come ILSpy ): il codice per l'operazione "SET" della proprietà viene compilato esattamente allo stesso modo: Proprietà decompilata con CallerMemberName

Quindi nessun uso della riflessione qui.

(campione compilato con VS2013)


2
Lo stesso link, ma in inglese invece che in francese: msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx
Mike de Klerk

2
@MikedeKlerk Non sono sicuro del motivo per cui non l'hai modificato direttamente nella risposta, anche se ora l'ho fatto.
Ian Kemp
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.