Traté de construir esto sobre la respuesta de @Andrey Naumov . Puede ser que esto sea una ligera mejora.
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;
}
}
Donde parámetro de tipo Ses el parámetro formal (el parámetro de entrada, que es el mínimo requerido para inferir el resto de los tipos). Ahora puedes llamarlo así:
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!");
Puede tener sobrecargas adicionales para Action<S>y de Expression<Action<S>>manera similar en la misma clase. Por otra construida en delegado y expresión tipos, tendrá que escribir clases separadas como Lambda, Lambda<S, T>, Lambda<S, T, U>etc.
Ventaja de esto que veo sobre el enfoque original:
Una especificación de tipo menos (solo se necesita especificar el parámetro formal).
Lo que le da la libertad de usarlo contra cualquiera Func<int, T>, no solo cuando Tse dice string, como se muestra en los ejemplos.
Admite expresiones de inmediato. En el enfoque anterior, tendrá que especificar tipos nuevamente, como:
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!");
para expresiones
Ampliar la clase para otros tipos de delegado (y expresión) es igualmente engorroso como el anterior.
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());
En mi enfoque, debe declarar tipos solo una vez (eso también es menos para Funcs).
Otra forma de implementar la respuesta de Andrey es como no ser completamente genérico
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;
}
Entonces las cosas se reducen a:
var l = Lambda<int>.Expression;
var e1 = l(x => x.ToString());
var e2 = l(x => "Hello!");
var e3 = l(x => x + x);
Eso es aún menos mecanografía, pero pierde cierta seguridad de tipografía, y eso no vale la pena.