Фон
Недавно я прочитал, что класс System.String в .NET 4 имеет новую перегрузку метода Join. Эта новая перегрузка принимает разделитель и IEnumerable<T>
, что позволяет объединять произвольные коллекции в одну строку без необходимости преобразования в массив промежуточных строк.
Cool! Это значит, что теперь я могу сделать это:
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0);
var list = string.Join(",",evenNums);
... вместо этого:
var evenNums = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.Select(i => i.ToString())
.ToArray();
var list = string.Join(",", evenNums);
... тем самым экономя на преобразовании каждого элемента в строку, а затем на выделении массива.
Проблема
Однако, будучи фанатом функционального стиля программирования в целом и цепочки методов в C # в частности, я бы предпочел написать что-то вроде этого:
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.string.Join(",");
Это не законно C #, хотя. Да, я мог бы сделать это с помощью Enumerable.Aggregate
, и да, я мог бы сделать это с помощью моего собственного метода расширения Join ), но эти подходы трудно читать / неэффективны и они выглядят как отбой (соответственно), поэтому я хотел бы попробовать и по-другому. Самое близкое, что мне удалось получить, это:
var list = Enumerable.Range(1, 100)
.Where(i => i%2 == 0)
.ApplyTo(
Functional.Curry<string, IEnumerable<object>, string>
(string.Join)(",")
);
... используя следующие методы расширения:
public static class Functional
{
public static TRslt
ApplyTo<TArg, TRslt>(this TArg arg, Func<TArg, TRslt> func)
{
return func(arg);
}
public static Func<T1, Func<T2, TResult>>
Curry<T1, T2, TResult>(this Func<T1, T2, TResult> func)
{
Func<Func<T1, T2, TResult>, Func<T1, Func<T2, TResult>>> curried
= f => x => y => f(x, y);
return curried(func);
}
}
Это довольно многословно, требует явного определения параметров и возвращаемого типа строки. Перегрузку, которую я хочу использовать, и она опирается на особенности дисперсии C # 4, потому что мы определяем один из аргументов как IEnumerable, а не IEnumerable.
Задача
Можете ли вы найти более точный способ достижения этого , используя стиль программирования "1035 *?
"
Эта задача состоит в том, чтобы попытаться найти краткий способ, в C #, карри функции, которая имеет несколько перегрузок - и это просто для удовольствия!