Я пытался построить это на ответ @ Андрей Наумов . Может быть, это небольшое улучшение.
public sealed class Lambda<S>
{
public static Func<S, T> CreateFunc<T>(Func<S, T> func)
{
return func;
}
public static Expression<Func<S, T>> CreateExpression<T>(Expression<Func<S, T>> expression)
{
return expression;
}
public Func<S, T> Func<T>(Func<S, T> func)
{
return func;
}
public Expression<Func<S, T>> Expression<T>(Expression<Func<S, T>> expression)
{
return expression;
}
}
Где параметр типа S
- это формальный параметр (входной параметр, минимальный необходимый для определения остальных типов). Теперь вы можете назвать это как:
var l = new Lambda<int>();
var d1 = l.Func(x => x.ToString());
var e1 = l.Expression(x => "Hello!");
var d2 = l.Func(x => x + x);
//or if you have only one lambda, consider a static overload
var e2 = Lambda<int>.CreateExpression(x => "Hello!");
Вы можете иметь дополнительные перегрузки для Action<S>
и Expression<Action<S>>
аналогично в том же классе. Для других встроенных типов делегатов и выражений вам придется написать отдельные классы, такие как Lambda
, Lambda<S, T>
, Lambda<S, T, U>
и т. Д.
Преимущество этого я вижу по сравнению с оригинальным подходом:
Еще одна спецификация типа (необходимо указать только формальный параметр).
Что дает вам свободу использовать его против любого Func<int, T>
, а не только когда T
, скажем, string
, как показано в примерах.
Поддерживает выражения сразу. При более раннем подходе вам придется снова указывать типы, например:
var e = Lambda<Expression<Func<int, string>>>.Cast(x => "Hello!");
//or in case 'Cast' is an instance member on non-generic 'Lambda' class:
var e = lambda.Cast<Expression<Func<int, string>>>(x => "Hello!");
для выражений.
Расширение класса для других типов делегатов (и выражений) также громоздко, как и выше.
var e = Lambda<Action<int>>.Cast(x => x.ToString());
//or for Expression<Action<T>> if 'Cast' is an instance member on non-generic 'Lambda' class:
var e = lambda.Cast<Expression<Action<int>>>(x => x.ToString());
В моем подходе вы должны объявлять типы только один раз (это тоже на один меньше для Func
с).
Еще один способ реализовать ответ Андрея - это не совсем универсальный
public sealed class Lambda<T>
{
public static Func<Func<T, object>, Func<T, object>> Func = x => x;
public static Func<Expression<Func<T, object>>, Expression<Func<T, object>>> Expression = x => x;
}
Итак, все сводится к:
var l = Lambda<int>.Expression;
var e1 = l(x => x.ToString());
var e2 = l(x => "Hello!");
var e3 = l(x => x + x);
Это еще меньше печатает, но вы теряете определенную безопасность шрифтов, и Имо, это того не стоит.