6

C# では、これを可能にする AppendCollection() という StringBuilder の拡張メソッドを構築しようとしています。

var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
var people = new List<Person>() { ...init people here... };
var orders = new List<Orders>() { ...init orders here... };

sb1.AppendCollection(people, p => p.ToString());
sb2.AppendCollection(orders, o => o.ToString());

string stringPeople = sb1.ToString();
string stringOrders = sb2.ToString();

stringPeople は、リスト内の各人物の行になります。各行は p.ToString() の結果です。stringOrders についても同様です。ラムダをジェネリックで動作させるコードの書き方がよくわかりません。

4

7 に答える 7

11

Func<T,string>デリゲートを使用します。

public static void AppendCollection<T>(this StringBuilder sb, 
                                       IEnumerable<T> collection, Func<T, string> method) {
   foreach(T x in collection) 
       sb.AppendLine(method(x));
}
于 2008-12-09T19:08:26.407 に答える
5
 public static void AppendCollection<T>(this StringBuilder builder, IEnumerable<T> list, Func<T,string> func)
        {
            foreach (var item in list)
            {
                builder.AppendLine(func(item));
            }
        }

文字列を返すのではなく、渡された元の Stringbuilder に追加するだけです。

于 2008-12-09T19:14:29.827 に答える
3

そんなに頑張る必要があるかどうかはわかりません:

 public static void AppendCollection( this StringBuilder builder,
                                      ICollection collection )
 {
     foreach (var item in collection)
     {
        builder.AppendLine( Convert.ToString( item ) );
     }
 }

使用されます

 List<Person> people = ...

 StringBuilder builder = new StringBuilder();
 builder.AppendCollection( people );
 var s = builder.ToString();

もちろん、 Person は ToString() をオーバーライドして、 Person オブジェクトの正しい出力を生成する必要があります。

于 2008-12-09T19:09:03.987 に答える
3

何かのようなもの:

  public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items, Func<TItem, string> valueSelector)
  {
       foreach(TItem item in items)
       {  
            builder.Append(valueSelector(item));
       }
  }

ケースの90%でラムダの指定を節約するために、便利なデフォルトを追加します...

   public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items)
  {
      AppendCollection(builder, items, x=>x.ToString());
   }
于 2008-12-09T19:09:40.040 に答える
3

私のバージョン:

    public static string AppendCollection<T>(this StringBuilder sb, IEnumerable<T> enumerable, Func<T, string> method)
    {
        List<T> l = new List<T>(enumerable);
        l.ForEach(item => sb.AppendLine(method(item)));
        return sb.ToString();
    }

ただし、この場合は文字列を返すべきではありません。私は次のことを好むでしょう:

    public static void AppendCollection<T>(this StringBuilder sb, IEnumerable<T> enumerable, Func<T, string> method)
    {
        List<T> l = new List<T>(enumerable);
        l.ForEach(item => sb.AppendLine(method(item)));
    }

次のように使用します。

        sb.AppendCollection(people, p => p.ToString());
        sb.AppendCollection(orders, o => o.ToString());
        Console.WriteLine(sb.ToString());
于 2008-12-09T19:29:09.970 に答える
2

このメソッドは何を返すと思われますか? 文字列を表示できますが、StringBuilder に追加している場合、なぜでしょうか?

やろうとしていることはかなり簡単ですが、何をしたいのかを正確に説明する必要があります。

アップデート:

これが私の見解です。新しい StringBuilder を渡して文字列を返すだけの場合、これに拡張メソッドを使用するのは愚かで無意味です。

更新 2:

その使用法を見たので、あなたがしていることは悪い習慣です。あなたが理想的にすべきことは、次のようなものです:

public static string Print<T>(this IEnumerable<T> col, Func<T,string> printer)
{
  var sb = new StringBuilder();
  foreach (T t in col)
  {
    sb.AppendLine(printer(t));
  }
  return sb.ToString();
}

string[] col = { "Foo" , "Bar" };
string lines = col.Print( s => s);

更新 3:

さらに明確にした後:

public static void AppendCollection<T>(this StringBuilder sb, 
   List<T> col, Func<T,string> printer)
{
  col.ForEach( o => sb.AppendLine(printer(o)));
}

(これはブルーノ・コンデが言ったのと同じです)

そして今、あなたはもうそれを本当に必要としません:)

于 2008-12-09T19:07:45.113 に答える
2
static class SBExtention
{
  static string AppendCollection<T>(this StringBuilder sb, 
                                    IEnumerable<T> coll, 
                                    Func<T,string> action)
  {
       foreach(T t in coll)
       {
          sb.Append(action(t));
          sb.Append("\n");
       }
       return sb.ToString();

  }
}

ただし、StringBuilder を返す方がよいと思います。そうすれば、チェーンできます:

  static StringBuilder AppendCollection<T>(this StringBuilder sb, 
                                    IEnumerable<T> coll, 
                                    Func<T,string> action)
  {
       // same
       return sb;

  }

文字列 peopleAndOrders = sb.AppendCollection(people, p => p.ToString()) .AppendCollection(orders, o => o.ToString()).ToString();

そして、デフォルトのケースについてジェニファーに同意します:

   public static StringBuilder AppendCollection<TItem>(
                  this StringBuilder builder, 
                  IEnumerable<TItem> items)
  {
      return AppendCollection(builder, items, x=>x.ToString());
   }

文字列 peopleAndOrders = sb.AppendCollection(people).AppendCollection(orders).ToString();

于 2008-12-09T19:11:54.590 に答える