2011-10-28 4 views
2

のこのスニペットから重複を削除します。がこのスニペットから重複を除去するのにアドバイスをお探しのコード

foreach (Car car in carList) { 
    DataRow row = NewRow(); 

    StringBuilder sbConfigurations = new StringBuilder();  
    foreach (ConfigurationItem configurationItem in car.Configurations) 
     sbConfigurations.AppendFormat("{0}: {1}\n", configurationItem.Name, configurationItem.Value); 

    row["configurations"] = sbConfigurations; 


    StringBuilder sbOptionals = new StringBuilder(); 
    foreach (OptionalItem optionalItem in car.Optionals) 
     sbOptionals.AppendFormat("{0}, ", optionalItem.Name); 

    row["optionals"] = sbOptionals; 

    Rows.Add(row); 
} 

EDIT:これは単純化文脈で、より多くのがあるかもしれないリスト加入これら

+0

私は何かを考えていましたインデックスの名前を持つ配列を使用していますが、その後、あなたは 'car.Optionals'を呼び出しているのを見ました。あなたは反射を使ってこれを行うことができますが、それはそれを良くしません。 – Marnix

+0

構成とオプションは共通の基本クラスから派生していますか?そうでなければ、有意な簡素化にはおそらく反映が含まれます。これをたくさんするつもりなら、おそらくobj.FormattedOutput( "{Name}:{Value} \ n")のような関数を書く努力を正当化することができます –

答えて

2

私は多くの重複がない同意するが、おそらくLINQの拡張 にこの「直訳は」あなたは(ブラウザタイプなので、テストしていません - まだ)探しているものです。

foreach (Car car in carList) { 
    DataRow row = NewRow(); 

    row["configurations"] = car.Configurations.Aggregate(new StringBuilder(), (a,i) => a.AppendFormat("{0}: {1}\n", i.Name, i.Value)); 
    row["optionals"] = car.Optionals.Aggregate(new StringBuilder(), (a,i) => a.AppendFormat("{0}, ", i.Name)); 

    Rows.Add(row); 
} 

また、あなたは多少読みやすく、それを書くことができstringbuildersなし(効率的/?):ラムダを抽出

はラインを短く:

Func<Car, string> nameValue = car => string.Format("{0}: {1}\n", car.Name, car.Value); 

foreach (var car in carList) { 
    var row = new Dictionary<string, string>(); 

    row["configurations"] = string.Join("\n", car.Configurations.Select(nameValue)); 
    row["optionals"]  = string.Join(", ", car.Optionals.Select(i => i.Name)); 

    list.Add(row); 
} 

C#4.0前に、逆さま問題を回しについてstring.Join

+0

はちょうど新しいC#の機能を学びました:P、私は同じ行に関数呼び出しが多すぎると思いますが、私はきれいなコードも探しています。 –

+1

Hehe。それをもう少し改善しました - 「長い行」の苦情に対処してください。 – sehe

3

Iドンのような本当にあなたが "複製"が必要であると言っているものを取り除くとは思わない。同一のコードが2回出現するのではなく、同じようなコードが2回出現します。これは一般的であり、心配することはありません。

+0

それでもポイントはありますが、行列の中の挿入リストを抽象化するために何かを実装してください。 –

+0

@arkilus:うん、そういうシンプルなケースで意味があるかどうかわからない、分で解決策を投稿する – sll

+0

私の例では、1回の繰り返ししかありません。これらの列は? –

2

方法の2番目のパラメータに関する追加.ToArray()の呼び出しを必要とします。関数をそれぞれのオブジェクトに対してDataRow形式を理解させる代わりに、各オブジェクトにDataRow形式を理解させるようにしてください。あなたは何のためにobject.ToString()を使用していない場合は、ConfigurationItemを作ることができるとOptionalItemobject.ToString()を実装:

class ConfigurationItem 
{ 
    public string override ToString() 
    { 
     return string.Format("{0}: {1}\n", Name, Value); 
    } 
} 

class OptionalItem 
{ 
    public string override ToString() 
    { 
     return string.Format("{0}, ", Name); 
    } 
} 

今、あなたは、オブジェクトのすべてのタイプのための単一のループを使用することができます:あなたがobject.ToString()が必要な場合は

string BuildDataRowString(IEnumerable collection) 
{ 
    var sb = new StringBuilder(); 
    foreach (var o in collection) sb.Append(o.ToString()); 
    return sb.ToString(); 
} 

row["configurations"] = car.Configurations.BuildDataRowString(); 
row["optionals"] = car.Optionals.BuildDataRowString(); 

を他の目的で、「DataRowフォーマット」のカスタムフォーマットを追加することができます:

class ConfigurationItem : IFormattable 
{ 
    public string override ToString(string format, IFormatProvider formatProvider) 
    { 
     if (format == "D") { 
      return string.Format(formatProvider, "{0}: {1}\n", Name, Value); 
     } 
     return this.ToString(); // otherwise format as default 
    } 
} 

class OptionalItem : IFormattable 
{ 
    public string override ToString(string format, IFormatProvider formatProvider) 
    { 
     if (format == "D") { 
      return string.Format(formatProvider, "{0}, ", Name); 
     } 
     return this.ToString(); // otherwise format as default 
    } 
} 

string BuildDataRowString(this IEnumerable e, string format) 
{ 
    StringBuilder sb = new StringBuilder(); 
    foreach (var o in e) sb.AppendFormat("{0:D}", o); 
    return sb.ToString(); 
} 
関連する問題