Хороший способ объединить строковые представления объектов?

2

Хорошо,

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

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"

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

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

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

Привет,

Эрик.

  • 0
    где здесь "в" состоянии?
Теги:
optimization
extension-methods
memory-management

5 ответов

5
Лучший ответ

Что касается первой проблемы, вы можете добавить еще один параметр "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());
}

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

  • 0
    Ли, я согласен с тобой. Это был мой оригинальный спор с моей командой. Нам еще предстоит показать какие-либо фактические узкие места производительности. По крайней мере, при таком подходе можно легко обновить реализацию в одном месте, и от этого выиграет все наше приложение.
  • 0
    +1 для Join предпочтения в качестве ссылки ниже , показывает , что разница в производительности незначительна и является предпочтительной читаемостью / простота.
3

По какой-то причине я подумал, что 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.

  • 4
    Join () использует прямой доступ к массиву char строки и будет по крайней мере таким же быстрым.
  • 0
    Стив, это интересно, вы демонстрируете мою озабоченность по поводу подхода StringBuilder. Если вы посмотрите вокруг, в вашем алгоритме есть десятки вариантов. На самом деле, вдохновленный методом String.Join () (спасибо Reflector), я бы, вероятно, следовал их шаблону. Я надеялся, что больше людей опубликуют здесь свой алгоритм и подтвердят свои предпочтения некоторыми достоверными данными. Но это интересная тема.
Показать ещё 2 комментария
0

это тоже сработает:

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

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

  • 0
    Поскольку это метод расширения, проверка на null коллекцию не имеет смысла. Проверка количества предметов в коллекции может быть хорошей.
  • 0
    Я не понимаю первую мысль - если это будет метод экземпляра, проверка его на нулевое значение не имеет смысла, но вы должны проверить последовательность, если это метод расширения, потому что он может быть вызван по нулевой ссылке.
0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню