#c# #functional-programming #stringbuilder
#c# #функциональное программирование #stringbuilder
Вопрос:
Недавно я читал о функциональном программировании. и я больше всего говорю, что это дает большие преимущества, но у меня есть некоторые проблемы с производительностью, например, при рендеринге очень большой строки, например, html-страницы, где я объединяю много строк. Обычно я бы использовал String builder. но я не мог использовать его, все еще следуя парадигме функционального программирования.
Низкая производительность кода:
Как вы можете видеть, ToListItem
и ToUl
являются чистыми функциями
class Program
{
static string ToListItem(string s)
{
return "<li>" s "</li>";
}
static string ToUl(string[] items)
{
return "<ul>" String.Join("", items.Select(x => ToListItem(x))) "</ul>";
}
static void Main(string[] args)
{
string[] items = new string[]
{
"Apple",
"Orange",
"Banana"
};
string htmlUl = ToUl(items);
Console.WriteLine(htmlUl);
}
}
Более быстрый код
Но, как вы можете видеть, ToListItem
и ToUl
больше не являются чистыми функциями, и я не смог предложить решение, которое использует StringBuilder
в чистых функциях
class Program
{
static void ToListItem(string s,StringBuilder sb)
{
sb.Append("<li>" s "</li>");
}
static void ToUl(string[] items, StringBuilder sb)
{
sb.Append("<ul>");
foreach (var item in items)
ToListItem(item, sb);
sb.Append("</ul>");
}
static void Main(string[] args)
{
string[] items = new string[]
{
"Apple",
"Orange",
"Banana"
};
StringBuilder sb = new StringBuilder();
ToUl(items, sb);
Console.WriteLine(sb.ToString());
}
}
Итак, мой вопрос:
Возможно ли использовать StringBuilder способом функционального программирования? Как? и если нет, то какое альтернативное решение с точки зрения производительности?
Update1 Я включил несколько примеров. производительность здесь не имеет значения, но по мере линейного роста списка разрыв в производительности будет расти экспоненциально.
Комментарии:
1. Я не уверен, почему вы думаете,
StringBuilder
что его нельзя использовать в кодировании в стиле функциональной парадигмы? Можете ли вы подробнее рассказать об этом?2. Пожалуйста, добавьте немного кода, чтобы было легче понять, какая у вас проблема
3. @Fildor потому что, когда я вызываю StringBuilder. Добавить Я изменяю состояние StringBuilder, и когда у меня сложная логика, мне нужно иметь более одной функции, и для использования string builder мне обычно приходится передавать его в качестве параметра.и вызовите Add во внутренней функции, что нарушает правила функционального программирования чистой функции .
4. Итак, вопрос в том, «разрешено ли мне использовать ссылки на объекты в качестве параметров в FP?» Ответ «нет».
5. Мне кажется, что вы столкнулись с концепцией FP и теперь пытаетесь внедрить ее повсюду. Пожалуйста, не делайте этого. Если вы хотите использовать чистый FP, делайте это на языке FP, таком как F #, в противном случае примите, что попытка использовать чистый FP на языке ООП, таком как C #, всегда будет компромиссом.
Ответ №1:
Это не совсем соответствует описанному выше случаю, но обеспечивает базовую основу, на которой вы могли бы создать что-то для своего случая, с параметрами верхнего и нижнего колонтитулов.
using System;
using System.Collections.Generic;
using System.Text;
public static class FunctionalStringBuilder
{
public static string BuildString<T>(this IEnumerable<T> enumerable, Func<T, string> response)
{
var builder = new StringBuilder();
foreach (var item in enumerable)
{
builder.Append(response(item));
}
return builder.ToString();
}
}
Вы можете использовать его следующим образом:
var list = new List<Employee>
{
AutoFaker.Generate<Employee>(),
AutoFaker.Generate<Employee>(),
AutoFaker.Generate<Employee>(),
AutoFaker.Generate<Employee>()
};
var result = list.BuildString(
e => $"Employee Id: {e.Id}, Name: {e.Name}, DateOfBirth: {e.DateOfBirth}n");
Комментарии:
1. Интересное решение.. но это не завершено . что, если дерево очень глубокое. затем в какой-то момент я буду рекурсивно вызывать BuildString и передавать строки по кругу. строки станут длиннее, а производительность упадет. Я искал способ передать String Builder для нескольких функций в отношении FP. но я думаю, что это все-таки невозможно :/
2. @DiaaEddin Хороший момент. Я видел такую возможность. Однако то, что метод может вызываться рекурсивно, не означает, что вы должны это делать.
3. @DiaaEddin Не уверен, что вам доступны эти инструменты, но мне пришло в голову, что вряд ли StringBuilder является правильным решением для вашего случая. Если вы можете, создайте тип, который можно сериализовать для разметки в виде дерева.