[CallerMemberName] est-il lent par rapport aux alternatives lors de l'implémentation d'INotifyPropertyChanged?

99

Il existe de bons articles qui suggèrent différentes manières de mettre en œuvreINotifyPropertyChanged .

Considérez l'implémentation de base suivante:

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

J'aimerais le remplacer par celui-ci:

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

Mais parfois, je lis que l' [CallerMemberName]attribut a de mauvaises performances par rapport aux alternatives. Est-ce vrai et pourquoi? Utilise-t-il la réflexion?

JYL
la source

Réponses:

201

Non, l'utilisation de [CallerMemberName]n'est pas plus lente que l'implémentation de base supérieure.

En effet, selon cette page MSDN ,

Les valeurs des informations sur l'appelant sont émises sous forme de littéraux dans le langage intermédiaire (IL) au moment de la compilation

On peut vérifier qu'avec n'importe quel désassembleur IL (comme ILSpy ): le code de l'opération "SET" de la propriété est compilé exactement de la même manière: Propriété décompilée avec CallerMemberName

Donc pas d'utilisation de Reflection ici.

(exemple compilé avec VS2013)

JYL
la source
2
Le même lien, mais en anglais au lieu de français: msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx
Mike de Klerk
2
@MikedeKlerk Je ne sais pas pourquoi vous ne l'avez pas édité directement dans la réponse, bien que je l'ai fait maintenant.
Ian Kemp