C # bir koleksiyon ekleyerek için StringBuilder uzantısı yöntemi

oy
5

C #, ben StringBuilder bunu yapmama izin ediyorum AppendCollection () denilen bir uzantısı yöntemi oluşturmak çalışıyorum:

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 listedeki her kişi için bir çizgi ile sona ereceğini. Her bir satır p.ToString sonucu olacaktır (). Benzer şekilde stringOrders için. Ben jenerik ile lambda'lar çalışması için kod yazma konusunda pek emin değilim.

Oluştur 09/12/2008 saat 20:03
kaynak kullanıcı
Diğer dillerde...                            


7 cevaplar

oy
9

Kullanım Func<T,string>temsilci.

public static void AppendCollection<T>(this StringBuilder sb, 
                                       IEnumerable<T> collection, Func<T, string> method) {
   foreach(T x in collection) 
       sb.AppendLine(method(x));
}
Cevap 09/12/2008 saat 20:08
kaynak kullanıcı

oy
4
 public static void AppendCollection<T>(this StringBuilder builder, IEnumerable<T> list, Func<T,string> func)
        {
            foreach (var item in list)
            {
                builder.AppendLine(func(item));
            }
        }

Ben sadece geçirildi orijinal stringbuilder sonuna ekler olurdu, bir dize dönmek olmazdı.

Cevap 09/12/2008 saat 20:14
kaynak kullanıcı

oy
3

Benim versiyonum:

    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();
    }

ancak bu durumda bir dize döndürür olmamalıdır. Aşağıdaki tercih ediyorum:

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

gibi kullanılacak:

        sb.AppendCollection(people, p => p.ToString());
        sb.AppendCollection(orders, o => o.ToString());
        Console.WriteLine(sb.ToString());
Cevap 09/12/2008 saat 20:29
kaynak kullanıcı

oy
3

Gibi bir şey:

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

Ben vakaların% 90'ında lambda specifiying kaydetmek için yararlı bir varsayılan eklersiniz ...

   public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items)
  {
      AppendCollection(builder, items, x=>x.ToString());
   }
Cevap 09/12/2008 saat 20:09
kaynak kullanıcı

oy
3

Bunu çok çalışmaya gerek emin değilim:

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

olarak kullanılır

 List<Person> people = ...

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

Tabii ki, Kişi bir Kişi nesnesi için doğru çıktı üretmek için ToString () geçersiz kılmak gerekir.

Cevap 09/12/2008 saat 20:09
kaynak kullanıcı

oy
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();

  }
}

Ancak, ben bunu StringBuilder dönmek zorunda için daha iyi olur bence. yapabildin bu şekilde zincirle:

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

  }

dize peopleAndOrders = sb.AppendCollection (insanlar, N => p.ToString ()) .AppendCollection (emir, o => o.ToString ()) .ToString (.);

Ve varsayılan dava hakkında Jennifer ile anlaşmak:

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

dize peopleAndOrders = sb.AppendCollection (kişi) .AppendCollection (emir) .ToString ();

Cevap 09/12/2008 saat 20:11
kaynak kullanıcı

oy
2

dönmek için diyelim ki bu yöntemi nedir? Eğer bir StringBuilder eklemeden eğer neden, bir dize görüyorum ama olabilir?

Ne yapmaya çalışıyorsun oldukça kolaydır, ancak tam olarak ne istediğinizi açıklamak gerekir.

Güncelleştirme:

İşte benim alabilir. Sadece yeni bir StringBuilder geçmek ve bir dize döndürmek için gidiyoruz eğer bunun için bir uzantısı yöntemi kullanarak aptal ve anlamsızdır.

Güncelleme 2:

Şimdi bunun kullanımını görmek olduğunu, ne yaptığını kötü bir uygulamadır. Ne ideal yapıyor olması gerektiği gibi bir şeydir:

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);

Güncelleme 3:

fazla açıklama sonra:

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

(Aynı olan Bruno conde kodlayan)

Ve şimdi gerçekten artık ona ihtiyacım yok :)

Cevap 09/12/2008 saat 20:07
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more