Método de extensión StringBuilder para agregar una colección en C #

votos
5

En C #, estoy tratando de construir un método de extensión para StringBuilder llamado AppendCollection () que me permita hacer esto:

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 terminaría con una línea para cada persona en la lista. Cada línea sería el resultado de p.ToString (). Del mismo modo para stringOrders. No estoy seguro de cómo escribir el código para que las lambdas funcionen con genéricos.

Publicado el 09/12/2008 a las 20:03
fuente por usuario
En otros idiomas...                            


7 respuestas

votos
9

Usa el Func<T,string>delegado.

public static void AppendCollection<T>(this StringBuilder sb, 
                                       IEnumerable<T> collection, Func<T, string> method) {
   foreach(T x in collection) 
       sb.AppendLine(method(x));
}
Respondida el 09/12/2008 a las 20:08
fuente por usuario

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

No devolvería una cadena, solo la agregaría al Stringbuilder original que se entregó.

Respondida el 09/12/2008 a las 20:14
fuente por usuario

votos
3

Mi version:

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

pero no deberías devolver una cadena en este caso. Yo preferiría lo siguiente:

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

para ser utilizado como:

        sb.AppendCollection(people, p => p.ToString());
        sb.AppendCollection(orders, o => o.ToString());
        Console.WriteLine(sb.ToString());
Respondida el 09/12/2008 a las 20:29
fuente por usuario

votos
3

Algo como:

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

Agregaría un valor predeterminado útil para guardar la especificación de la lambda en el 90% de los casos ...

   public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items)
  {
      AppendCollection(builder, items, x=>x.ToString());
   }
Respondida el 09/12/2008 a las 20:09
fuente por usuario

votos
3

No estoy seguro de que deba trabajar tan duro:

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

Usado como

 List<Person> people = ...

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

Por supuesto, la persona debe anular ToString () para producir el resultado correcto para un objeto Person.

Respondida el 09/12/2008 a las 20:09
fuente por usuario

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

  }
}

Sin embargo, creo que será mejor que lo devuelva StringBuilder. De esa manera podrías encadenarlo:

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

  }

string peopleAndOrders = sb.AppendCollection (personas, p => p.ToString ()) .AppendCollection (pedidos, o => o.ToString ()). ToString ();

Y estoy de acuerdo con Jennifer sobre el caso predeterminado:

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

string peopleAndOrders = sb.AppendCollection (personas) .AppendCollection (orders) .ToString ();

Respondida el 09/12/2008 a las 20:11
fuente por usuario

votos
2

¿Qué se supone que debe devolver este método? Puedo ver una cadena, pero ¿por qué, si agregas un StringBuilder?

Lo que intenta hacer es bastante fácil, pero necesita explicar exactamente lo que quiere.

Actualizar:

Aquí está mi opinión. Usar un método de extensión para esto es estúpido e inútil si solo vas a pasar un nuevo StringBuilder y devolver una cadena.

Actualización 2:

Ahora que veo ese uso, lo que estás haciendo es una mala práctica. Lo que idealmente deberías estar haciendo es algo así como:

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

Actualización 3:

Después de más aclaraciones:

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

(que es lo mismo que dijo el conde bruno)

Y ahora no lo necesitas más :)

Respondida el 09/12/2008 a las 20:07
fuente por usuario

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