StringBuilder метод расширения для добавления коллекции в C #

голоса
5

В C #, я пытаюсь построить метод расширения для StringBuilder называется AppendCollection (), что позволит мне сделать это:

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. Я не совсем уверен, как писать код, чтобы сделать работу с лямбды дженериков.

Задан 09/12/2008 в 20:03
источник пользователем
На других языках...                            


7 ответов

голоса
9

Используйте 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));
}
Ответил 09/12/2008 в 20:08
источник пользователем

голоса
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));
            }
        }

Я бы не возвращать строку, я бы просто добавить его к первоначальному StringBuilder, который был принят в.

Ответил 09/12/2008 в 20:14
источник пользователем

голоса
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());
Ответил 09/12/2008 в 20:29
источник пользователем

голоса
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));
       }
  }

Я хотел бы добавить в полезном умолчанию для сохранения specifiying лямбды в 90% случаях ...

   public static void AppendCollection<TItem>(this StringBuilder builder, IEnumerable<TItem> items)
  {
      AppendCollection(builder, items, x=>x.ToString());
   }
Ответил 09/12/2008 в 20:09
источник пользователем

голоса
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();

Конечно, человек должен переопределить ToString () для получения правильного вывода для объекта Person.

Ответил 09/12/2008 в 20:09
источник пользователем

голоса
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 (люди, р => p.ToString ()) .AppendCollection (приказы, о => o.ToString ()) ToString ().

И я согласен с Дженнифер о случае по умолчанию:

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

Строка peopleAndOrders = sb.AppendCollection (люди) .AppendCollection (приказы) .ToString ();

Ответил 09/12/2008 в 20:11
источник пользователем

голоса
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)));
}

(Который является таким же, как Брюно Conde сказал)

И теперь вы действительно не нужно больше :)

Ответил 09/12/2008 в 20:07
источник пользователем

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