Хороший способ объединить строковые представления объектов? - PullRequest
2 голосов
/ 27 октября 2009

Хорошо,

У нас есть много , где предложений в нашем коде. У нас есть столько же способов сгенерировать строку для представления условия in . Я пытаюсь придумать чистый способ:

public static string Join<T>(this IEnumerable<T> items, string separator)
{
    var strings = from item in items select item.ToString();
    return string.Join(separator, strings.ToArray());
}

может использоваться следующим образом:

var values = new []{1, 2, 3, 4, 5, 6};
values.StringJoin(",");
// result should be:
// "1,2,3,4,5,6"

Так что это хороший метод расширения, который выполняет очень простую работу. Я знаю, что простой код не всегда превращается в быстрое или эффективное выполнение, но мне просто любопытно, что я мог упустить из-за этого простого кода. Другие члены нашей команды утверждают, что:

  • недостаточно гибкий (без контроля над строковым представлением)
  • может быть неэффективно при использовании памяти
  • не может быть быстрым

Любой эксперт , чтобы вмешаться?

С уважением,

Эрик.

Ответы [ 5 ]

5 голосов
/ 27 октября 2009

Что касается первой проблемы, вы можете добавить еще один параметр 'formatter' для управления преобразованием каждого элемента в строку:

public static string Join<T>(this IEnumerable<T> items, string separator)
{
    return items.Join(separator, i => i.ToString());
}

public static string Join<T>(this IEnumerable<T> items, string separator, Func<T, string> formatter)
{
    return String.Join(separator, items.Select(i => formatter(i)).ToArray());
}

Что касается вторых двух проблем, я не стал бы беспокоиться об этом, если вы позже не столкнетесь с проблемами производительности и не обнаружите, что это проблема. Однако вряд ли это будет узким местом ...

3 голосов
/ 27 октября 2009

Почему-то я думал, что String.Join реализован в терминах StringBuilder класса. Но если это не так, то следующее, вероятно, будет работать лучше для больших входных данных, поскольку оно не воссоздает объект String для каждого соединения в итерации.

public static string Join<T>(this IEnumerable<T> items, string separator)
{
    // TODO: check for null arguments.
    StringBuilder builder = new StringBuilder();
    foreach(T t in items)
    {
        builder.Append(t.ToString()).Append(separator);
    }

    builder.Length -= separator.Length;
    return builder.ToString();
}

РЕДАКТИРОВАТЬ : Вот анализ того, когда целесообразно использовать StringBuilder и String.Join.

0 голосов
/ 27 октября 2009

Вам не хватает нулевых проверок последовательности и элементов последовательности. И да, это не самый быстрый и самый эффективный способ памяти. Можно было бы просто перечислить последовательность и преобразовать строковые представления элементов в StringBuilder. Но действительно ли это имеет значение? У вас проблемы с производительностью? Вам нужно оптимизировать?

0 голосов
/ 27 октября 2009

Почему бы вам не использовать StringBuilder, а самим перебирать коллекцию, добавляя. В противном случае вы создаете массив строк (var strings), а затем делаете Join.

0 голосов
/ 27 октября 2009

это также будет работать:

public static string Test(IEnumerable<T> items, string separator)
{
    var builder = new StringBuilder();
    bool appendSeperator = false;
    if(null != items)
    {
        foreach(var item in items)
        {
            if(appendSeperator)
            {
                builder.Append(separator)
            }

            builder.Append(item.ToString());

            appendSeperator = true;
        }
   }

   return builder.ToString();
}
...