Apakah [CallerMemberName] lambat dibandingkan dengan alternatif saat mengimplementasikan INotifyPropertyChanged?

98

Ada artikel bagus yang menyarankan berbagai cara untuk menerapkanINotifyPropertyChanged .

Pertimbangkan implementasi dasar berikut:

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

Saya ingin menggantinya dengan yang ini:

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

Tetapi terkadang saya membaca bahwa [CallerMemberName]atribut tersebut memiliki kinerja yang buruk dibandingkan dengan alternatif. Apakah itu benar dan mengapa? Apakah itu menggunakan refleksi?

JYL
sumber

Jawaban:

200

Tidak, penggunaan [CallerMemberName]tidak lebih lambat dari implementasi dasar atas.

Ini karena, menurut halaman MSDN ini ,

Nilai Info Penelepon dipancarkan sebagai literal ke Intermediate Language (IL) pada waktu kompilasi

Kita dapat memeriksanya dengan disassembler IL (seperti ILSpy ): kode untuk operasi "SET" dari properti dikompilasi persis dengan cara yang sama: Properti terdekompilasi dengan CallerMemberName

Jadi tidak ada gunanya Refleksi di sini.

(sampel dikompilasi dengan VS2013)

JYL
sumber
2
Tautan yang sama, tetapi dalam bahasa Inggris, bukan Prancis: msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx
Mike de Klerk
2
@MikedeKlerk Tidak yakin mengapa Anda tidak mengeditnya langsung ke jawaban, meskipun sekarang saya sudah melakukannya.
Ian Kemp