2009-04-09 9 views
7

私は、基礎となるチェックボックスのテキストまたはタグを基本的にCSV文字列として変換する2つのメソッドを持っています。
これらの2つの方法から共通の機能をリファクタリングできますか?

これらの2つの方法

  • GetSelectedTextAsCsv()
  • GetTagAsCsv()

のみれるは型であるSelectedCheckBoxesから値を抽出するために異なるIList<CheckBox>

public string GetSelectedTextAsCsv() 
    { 
     var buffer = new StringBuilder(); 
     foreach (var cb in SelectedCheckBoxes) 
     { 
      buffer.Append(cb.Text).Append(","); 
     } 
     return DropLastComma(buffer.ToString()); 
    } 

    public string GetTagAsCsv() 
    { 
     var buffer = new StringBuilder(); 
     foreach (var cb in SelectedCheckBoxes) 
     { 
      buffer.Append(cb.Tag).Append(","); 
     } 
     return DropLastComma(buffer.ToString()); 
    } 

私はFunc<T, TResult>を返すメソッドを抽出しようとしていましたが、どのように取り除くことができないのかはわかりません。 私の貧弱な試みは、以下のようなものだったが、私は、私は間違ってトラックに午前いる場合、あなたはどのように私ができるの私に助言してくださいだろうConvertToCsv()

public Func<T, string> ConvertToCsv<T>() 
    { 
     return propertyName => 
     { 
      var buffer = new StringBuilder(); 
      foreach (var checkBox in SelectedCheckBoxes) 
      { 
       buffer.Append(
        /* How can you abstract this portion? like following? */ 
        checkBox.propertyName 
       ).Append(","); 
      } 
      return DropLastComma(buffer.ToString()); 
     }; 
    } 

内のコメントに示すように、プロパティ部分を抽出する方法を見つけ出すことはできません一般的な方法を使用するコードの上のリファクタリング?

[UPDATE 1]ここでブライアンとジョンの答え

public string ConvertToCsv<T>(Func<CheckBox, T> getValue) 
    { 
     var stringValues = SelectedCheckBoxes.Select(
      cb => getValue(cb).ToString()).ToArray(); 
     return string.Join(",", stringValues); 
    } 

    public string GetSelectedTextAsCsv() 
    { 
     return ConvertToCsv(cb => cb.Text); 
    } 

    public string GetTagAsCsv() 
    { 
     return ConvertToCsv(cb => cb.Tag); 
    } 

両方の組み合わせである[UPDATE 2]バージョン2

public string GetAsCsv<T>(Func<CheckBox, T> getValue) 
    { 
     return string.Join(",", SelectedCheckBoxes.Select(
      cb => getValue(cb).ToString()).ToArray()); 
    } 

    public string GetSelectedTextAsCsv() 
    { 
     return GetAsCsv(cb => cb.Text); 
    } 

    public string GetTagAsCsv() 
    { 
     return GetAsCsv(cb => 
      cb.Tag == null ? string.Empty : cb.Tag.ToString()); 
    } 

[UPDATE 3]メイド CheckBoxおよび文字列の閉じた汎用としてGetAsCsv()のパラメータ

Func<CheckBox, T>~Func<CheckBox, string>

これにより、私はGetAsCsv()をさらに簡単で読みやすくすることができました。

その後
private string GetAsCsv(Func<CheckBox, string> getValue) 
{ 
    return string.Join(",", SelectedCheckBoxes.Select(getValue).ToArray()); 
} 

答えて

22
public string GetAsCsv(Func<CheckBox, string> getValue) 
{ 
    var buffer = new StringBuilder(); 
    foreach (var cb in SelectedCheckBoxes) 
    { 
     buffer.Append(getValue(cb)).Append(","); 
    } 
    return DropLastComma(buffer.ToString()); 
} 

GetAsCsv(cb => cb.Tag != null ? cb.Tag.ToString() : string.Empty); 
GetAsCsv(cb => cb.Text); 
+0

私は実際にあなたのソリューションとJon'sを使用しています。決定するのが難しい... – Sung

+0

w00t!機能プログラミング:) – Juliet

+0

@Princess:それは関数型プログラミングのアプローチですか?私はそれを意識していなくても... – Sung

0

二つの機能は、あなたが開始する必要がどこつまり、ゲッターのため除いてまったく同じあるので:可動部。

はまだ私のC#をブラッシュアップしていないが、の線に沿って何か:

public string GetCsv(Func<string> getter) 
    { 
     var buffer = new StringBuilder(); 
     foreach (var cb in SelectedCheckBoxes) 
     { 
      buffer.Append(getter()).Append(","); 
     } 
     return DropLastComma(buffer.ToString()); 
    } 

は動作するはずです。また、SelectedCheckBoxesを変数にしますか?

+0

あなたは間違った質問を読んで、SelectedCheckBoxesは可変で、cbで使用されるプロパティは可変です。 – Samuel

19

私が代わりにstring.Joinを使用したい:

string tags = string.Join(",", 
        SelectedCheckBoxes.Select(cb => Convert.ToString(cb.Tag)) 
            .ToArray()); 
string text = string.Join(",", 
        SelectedCheckBoxes.Select(cb => cb.Text).ToArray()); 

は確かに、あなたはメソッドにそれを置くこともできますが、私はおそらくちょうど2つのコールのために気にしないでしょう。

あなたは、しかし、ここではそれがブライアンのテンプレートを使用してどのように見えるかだと思った場合:

public string GetAsCsv(Func<CheckBox, string> getValue) 
{ 
    string[] array = SelectedCheckBoxes.Select(getValue).ToArray(); 
    return string.Join(",", array); 
} 
+0

非常に良い削減。 –

+0

うわー。今すぐ "DropLastComma()"を完全に削除することができます – Sung

+0

string.Joinは文字列[]を期待していませんか?これはオブジェクトであるTagに対してどのように機能しますか? –

2

あなたは、ラムダを使用することができます。

public string ConvertToCSV(Func<CheckBox, string> cb_prop) { 
    ... 
    buffer.Append(cb_prop(cb)).Append(","); 
    ... 

} 

ConvertToCSV(c => c.Tag); 
1

私はIEnumerableを周りの短い拡張メソッドを記述します。あなたが行うことができ、その後

public static string Join(this IEnumerable<string> strings, string separator) 
{ 
    return string.Join(separator, strings.ToArray()); 
} 

::区切りを取った文字列

var text = SelectedCheckBoxes.Select(cb => cb.Text).Join(", "); 
var tags = SelectedCheckBoxes.Select(cb => (string)cb.Tag).Join(", "); 
関連する問題