5

私は autoproperties を持つビジネスクラスをたくさん持っています:

public class A {

    public int Id { get; set; }
    public string Title { get; set;}

}

アプリケーションが進化するため、変更されたデータのみをバッキング ストアに送信するために、プロパティの変更の追跡を有効にするという新しい要件があります。

この目標を達成するには、次のようにすべてのプロパティをフィールド + プロパティに変換する必要があります。

public class A {

    private int m_Id;
    public int Id {
        get { return m_Id; }
        set {
            if(m_Id != value){
                SetChanged("Id");
                m_Id = value;
            }
        }
    }
    private string m_Title;
    public string Title 
    { 
        get { return m_Title; }
        set {
            if(m_Title != value){
                SetChanged("Title");
                m_Title = value;
            }
        }
    }

    protecte void SetChanged(string propertyName) { 
        // Not important here
    }
}

プロパティを手動で変更する必要がないようにコードをすばやくリファクタリングする方法はありますか?

4

4 に答える 4

3

IDE でこれを行う方法はありませんが、すべての X プロパティを置き換える必要がある場合は、それを行うための短いコンソール アプリケーションを作成します。

プロセスは次のようになります。

  • *.cs に一致するディレクトリ内のすべてのファイルを反復処理します
  • Foreach ファイル、正規表現は古いプロパティを検索して新しいプロパティ構文に置き換えます

正規表現を使用したマッチングは非常に強力です。VS2010 で正規表現を使用して、検索/置換操作を実行できます。これを見つけようとすると(正規表現が有効になっている場合)

{(public|private|internal|protected)}:b{[a-zA-Z0-9]+}
:b{[a-zA-Z0-9]+}:b\{ get; set; \}

このようなプロパティに一致します

public Type Foo { get; set; }

コンソール アプリケーションで、上記に一致するすべてのコード行を見つけてから、それらを Modifier、Type、Property Name に分割し、最後にブロック全体を次のようなものに置き換えます。

// PS: this is pseudocode ;-) or could be your new property template
private [Type] m_[PropertyName].ToPascaleCase
public [Type] PropertyName
{
    get { return m_[PropertyName].ToPascaleCase; }
    set
    {
        if(m_[PropertyName].ToPascaleCase != value){
            SetChanged([PropertyName]);
            m_[PropertyName].ToPascaleCase = value;
        }
    }
}

最後に、チェックインする前に、コードのバックアップを取るか、このテストをオフラインで実行してテストすることをお勧めします!!

于 2012-07-05T15:48:09.177 に答える
1

割り当てと呼び出しを行うジェネリックメソッドをいつでも作成できますSetChange

void SetChangeIfNeeded<T>(ref T field, T value, string propertyName)
{
    if (!EqualityComparer<T>.Default.Equals(field, value))
    {
        field = value;
        SetChanged(property);
    }
}

プライベート バック フィールドが必要です。クラスは次のようになります。

public class A {  

    private int m_id
    public int Id 
    { 
        get { return m_id };
        set { SetChangeIfNeeded<int>(ref m_id, value, "Id"); }
    }  
}  
于 2012-07-05T15:45:15.023 に答える
0

おそらく、屈折でこれを行う直接的な方法はありません。これが私の問題だったら。これを生成するコードを作成します。

public string MakePropertyBigger(string varName, string propName, string dataType)
{
    string output = "";
    output += string.Format("private {0} {1};", dataType, varName) + Environment.NewLine;
    output += string.Format("public {0} {1}", dataType, propName) + Environment.NewLine;
    output += "{" + Environment.NewLine;
    output += string.Format("get { return {0}; }", varName) + Environment.NewLine;
    output += string.Format("set { if({0} != value){ SetChanged(\"{1}\");", varName, propName) + Environment.NewLine;
    output += string.Format("{0} = value; }", varName) + Environment.NewLine;
    output + "}" + Environment.NewLine + "}";

今すぐこれを差し込んで、それを一気飲みしてください。

于 2012-07-05T15:51:57.863 に答える
0

ReSharper はこれを行うことができますが、セッターを変更しません。

public string Title {
    get { return m_title; }
    set { m_title = value; }
}
于 2012-07-05T15:40:28.247 に答える