I tried to build this upon @Andrey Naumov's answer. May be this is a slight improvement.
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;
}
}
Where type parameter S
is the formal parameter (the input parameter, which is minimum required to infer rest of the types). Now you can call it like:
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!");
You can have additional overloads for Action<S>
and Expression<Action<S>>
similarly in the same class. For other built in delegate and expression types, you will have to write separate classes like Lambda
, Lambda<S, T>
, Lambda<S, T, U>
etc.
Advantage of this I see over the original approach:
One less type specification (only the formal parameter needs to be specified).
Which gives you the freedom to use it against any Func<int, T>
, not just when T
is say, string
, as shown in examples.
Supports expressions straight away. In the earlier approach you will have to specify types again, like:
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!");
for expressions.
Extending the class for other delegate (and expression) types is similarly cumbersome like above.
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());
In my approach you have to declare types only once (that too one less for Func
s).
One another way to implement Andrey's answer is like not going fully generic
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;
}
So things reduce to:
var l = Lambda<int>.Expression;
var e1 = l(x => x.ToString());
var e2 = l(x => "Hello!");
var e3 = l(x => x + x);
That's even less typing, but you lose certain type safety, and imo, this is not worth it.