2012-07-05 9 views
5

私はautopropertiesとビジネスクラスの束を持っています。 、私はこのようなフィールド+プロパティにすべてのプロパティを変換する必要があり、この目標を達成するためにフィールドとgetter/setterプロパティに対するC#の自動プロパティをリファクタリングしますか?アプリケーションが進化する</p> <pre><code>public class A { public int Id { get; set; } public string Title { get; set;} } </code></pre> <p>ので、データのみを変更バッキングストアに送信するためには、プロパティの変更を追跡可能にするための新しい要件がある:

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

迅速手動でプロパティを変更することを避けるために自分のコードをリファクタリングする方法はありますか?

+3

すべてのビジネスクラスが単純に自動作成機能を持つクラスであれば、私は[T4 templates](http://www.hanselman.com/blog/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx)を使用してクラスを生成します。それで、上記のようにすべてを再フォーマットするのは簡単な変更です。 – mellamokb

+5

Regexの置き換えはうまくいくかもしれません - Resharperもこのようなことがありますが、おそらく順番にそれぞれを行う必要があります。また、CodeSmithテンプレートは、それを使用する方法を知っていることを前提に、時間外にそれを並べ替えるでしょう。それ以外の場合は、適切な構造を持ち、プロパティを再実行するコードスニペットを作成します。コードスニペットは私が想定しているすべてのビットを埋めるでしょうが、それはまだ手作業です!私は正規表現のために行くだろう...またはmellamokbが言うように、T4のテンプレートは、私は単純なもののために彼らと良い成功を収めてきた – Charleh

+0

Resharperを使用していますか?そうであれば、それはショートカットであり、誰かが自動的にINotifyPropertyChangedサポートを追加するように拡張しています:https://bitbucket.org/tgmayfield/resharper.tgmcontrib –

答えて

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"); } 
    } 
} 
+0

これがコードを単純化しても、これは手動ですべてのプロパティを手動で更新する必要があります。 –

+0

私は実際にこのメソッドを使用しているので、あなたの答えはソリューションとして設定しました。私は実際にいくつかのステップを実行しました。まず、CodeRush XPressを使用して、自作のプロパティをバッキングフィールドの取得/設定されたプロパティにリファクタリングします。次に、あなたのメソッドをベースクラスに追加しました。最後に、私はVisual Studio Replace w/Reg exを使って、 'SetValue(ref _ $ 1、value、" $ 1 ");'で '_(\ w +)= value'を抽出します。正規表現は任意のフィールドセッターにマッチし、メソッドへの呼び出しで置き換えます。 –

+0

さらに検索すると、 'public([\ w?] +)(\ w +){get;セット; }}を置き換えて 'public $ 1 $ 2 {get {return m_ $ 2;}} {SetValue(ref m_ $ 2、value、" $ 2 ");}}プライベート$ 1 m_ $ 2;これにより、リファクタリングステップが回避され、オートプロップが自動的に抽出されます。 –

0

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

public string Title { 
    get { return m_title; } 
    set { m_title = value; } 
} 
3

あり、これを行うためのIDEには方法はませんが、あなたはすべてのXプロパティを交換する必要がある場合、私はそれを行うには、短いコンソールアプリケーションを記述します。あなたのクラスには、次のようになります。

プロセスは次のようになります。ディレクトリのマッチング* .csファイル内のすべてのファイルを超える

  • 反復
  • foreachのファイル、正規表現を見つけると新しいプロパティの構文の古いプロパティを置き換えるために正規表現を使用して

マッチは非常に強力です。 Regexは、VS2010で検索/置換操作を行うために使用できます。あなたは(正規表現を有効にして)

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

これを発見しようとした場合には、上記に一致するすべてのコード行が、その後にそれらを分割開始見つけるあなたのコンソールアプリケーションでこの

public Type Foo { get; set; } 

などのプロパティと一致します修飾子、型、プロパティ名と最終的にはこの

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

最後に、私はあなたのコードのバックアップを取るか、このテストを実行している提唱うようなもので、ブロック全体を交換しますチェックインの前にフリ린とテスト!

+0

「バックアップを取る」、++++ 1 :) –

+0

笑、馬鹿だと言うと馬鹿に聞こえるが、あなたは正しいことは決してないだろうか? –

+0

私はメモ帳++を使って、プロジェクトソリューションでAからBのすべてのものを置き換えることを初めて学びました。 –

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 + "}"; 

これをプラグインして、それを詰めてください。

関連する問題

 関連する問題