112

を実装するためのさまざまな方法を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]属性に比べてパフォーマンスが悪いと読むことがあります。それは本当ですか、なぜですか? リフレクションを使用していますか?

4

1 に答える 1

224

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

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

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

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

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

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

于 2014-03-22T16:55:44.403 に答える