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 S
es 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 T
se 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 Func
s).
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.