5

INotifyPropertyChanged の正しい実装を強制する簡単な方法を探しています。つまり、PropertyChanged が発生したときに、実際に定義されているプロパティを参照する必要があります。Microsoft の新しい CodeContract ツールでこれを実行しようとしましたが、「CodeContracts: requires unproven」という警告が引き続き表示されます。これが私のコードです...

public sealed class MyClass : INotifyPropertyChanged
{
    private int myProperty;
    public int MyProperty
    {
        get
        {
            return myProperty;
        }
        set
        {
            if (myProperty == value)
            {
                return;
            }

            myProperty = value;
            OnPropertyChanged("MyProperty");
        }
    }

    private void OnPropertyChanged(string propertyName)
    {
        Contract.Requires(GetType().GetProperties().Any(x => x.Name == propertyName));

        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

とにかくこれを機能させる方法はありますか?

4

3 に答える 3

3

まず、この目的のために、MVVM Foundationの ObservableObject 実装を個人的に使用します。これは、デバッグ ビルドのみのランタイム チェックであり、あなたのものとほぼ同じです。

public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged(string propertyName)
{
    this.VerifyPropertyName(propertyName);

    PropertyChangedEventHandler handler = this.PropertyChanged;
    if (handler != null)
    {
        var e = new PropertyChangedEventArgs(propertyName);
        handler(this, e);
    }
}

[Conditional("DEBUG")]
[DebuggerStepThrough]
public void VerifyPropertyName(string propertyName)
{
    // Verify that the property name matches a real,  
    // public, instance property on this object.
    if (TypeDescriptor.GetProperties(this)[propertyName] == null)
    {
        string msg = "Invalid property name: " + propertyName;

        if (this.ThrowOnInvalidPropertyName)
            throw new Exception(msg);
        else
            Debug.Fail(msg);
    }
}

おそらく最も簡単な方法ですが、特定の欠点があります。いくつかの基本クラスから継承できるようにする必要があります。これは実行時にのみ機能します(ただし、これは私の wpf の経験では常に十分でした)。確かに「パッチ」のように見えます。静的チェックが欠落している場合。

この場合、静的分析/静的ツールを有効にする方法はいくつかあります。

  1. マークが言うように、ラムダ表記を使用し、実行時に文字列を抽出します
  2. カスタム FxCop ルールを作成します
  3. AOP ツールを使用して、メタ マークアップを含むコードを後処理します。

CodeContracts に関しては、静的解析でこの種のチェックを処理するには、まだ十分に成熟していないと思います。ラムダを解析し、間違った によってどのように失敗するかを理解し、propertyNameこのメソッドへのすべての呼び出しを見つけ、可能なすべての入力を把握する必要があると想像してください。そのようなチェックには間違った手段です。

于 2009-10-29T23:32:42.657 に答える
1

静的分析ツールを意味していると思いますか?(少なくともランタイムチェックが機能することを期待します-そしておそらくデバッグビルドにそれを残すことができます)。これが静的分析で透けて見えるものではないかと思います-GetType().GetProperties()単純に複雑すぎるなどです。

要するに; 疑わしいです...ラムダ(Expression)はオプションですが、文字列だけを渡すよりもはるかに低速です。

于 2009-10-25T20:08:41.730 に答える