web-dev-qa-db-ja.com

INotifyPropertyChangedを実装する場合、[CallerMemberName]は他の選択肢と比較して遅いですか?

INotifyPropertyChangedを実装するさまざまな方法 を提案する優れた記事があります。

次の基本的な実装を検討してください。

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

私はこれをこれに置き換えたい:

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

しかし、時々[CallerMemberName]属性は、他の属性と比較してパフォーマンスが劣ります。それは本当ですか、なぜですか?リフレクションを使用していますか?

88
JYL

いいえ、[CallerMemberName]の使用は、上位の基本実装より遅くありません

これは、 このMSDNページ によると、

発信者情報の値は、コンパイル時に中間言語(IL)にリテラルとして出力されます

ILの逆アセンブラ( ILSpy など)で確認できます。プロパティの「SET」操作のコードは、まったく同じ方法でコンパイルされます。 Decompiled property with CallerMemberName

したがって、ここではReflectionを使用しません。

(VS2013でコンパイルされたサンプル)

181
JYL