Czy usługa [CallerMemberName] jest wolna w porównaniu z alternatywami podczas wdrażania INotifyPropertyChanged?

98

Istnieją dobre artykuły, które sugerują różne sposoby implementacjiINotifyPropertyChanged .

Rozważ następującą podstawową implementację:

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

Chciałbym go zastąpić tym:

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

Ale czasami czytam, że [CallerMemberName]atrybut ma słabe wyniki w porównaniu z alternatywami. Czy to prawda i dlaczego? Czy używa refleksji?

JYL
źródło

Odpowiedzi:

200

Nie, użycie [CallerMemberName]nie jest wolniejsze niż górna podstawowa implementacja.

To dlatego, że według tej stronie MSDN ,

Wartości informacji o dzwoniącym są emitowane jako literały do ​​języka pośredniego (IL) w czasie kompilacji

Możemy to sprawdzić dowolnym deasemblerem IL (takim jak ILSpy ): kod operacji „SET” właściwości jest kompilowany dokładnie w ten sam sposób: Decompiled Właściwość z CallerMemberName

Więc nie ma tu zastosowania Refleksji.

(próbka skompilowana z VS2013)

JYL
źródło
2
Ten sam link, ale w języku angielskim zamiast francuskim: msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx
Mike de Klerk
2
@MikedeKlerk Nie jestem pewien, dlaczego nie podałeś go bezpośrednio w odpowiedzi, chociaż już to zrobiłem.
Ian Kemp,