¿Es [CallerMemberName] lento en comparación con las alternativas al implementar INotifyPropertyChanged?

98

Hay buenos artículos que sugieren diferentes formas de implementaciónINotifyPropertyChanged .

Considere la siguiente implementación 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
            }
        }
    }
}

Me gustaría reemplazarlo con 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();
            }
        }
    }
}

Pero a veces leo que el [CallerMemberName]atributo tiene malos resultados en comparación con las alternativas. ¿Es eso cierto y por qué? ¿Utiliza la reflexión?

JYL
fuente

Respuestas:

200

No, el uso de [CallerMemberName]no es más lento que la implementación básica superior.

Esto se debe a que, según esta página de MSDN ,

Los valores de información de la persona que llama se emiten como literales en el lenguaje intermedio (IL) en tiempo de compilación

Podemos comprobar eso con cualquier desensamblador de IL (como ILSpy ): el código para la operación "SET" de la propiedad se compila exactamente de la misma manera: Propiedad descompilada con CallerMemberName

Así que no hay uso de Reflection aquí.

(muestra compilada con VS2013)

JYL
fuente
2
El mismo enlace, pero en inglés en lugar de francés: msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx
Mike de Klerk
2
@MikedeKlerk No estoy seguro de por qué no lo editó directamente en la respuesta, aunque ya lo hice.
Ian Kemp