Я намагався будувати це на відповіді @Andrey Наумова . Можливо, це незначне поліпшення.
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
s).
Ще один спосіб втілити відповідь Андрія - це не так, щоб вийти не загальним
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);
Це ще менше вводити текст, але ви втрачаєте безпеку певного типу, і imo, цього не варто.