Ich habe versucht, dies auf der Antwort von @Andrey Naumov aufzubauen . Möglicherweise ist dies eine leichte Verbesserung.
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;
}
}
Dabei S
ist der Typparameter der formale Parameter (der Eingabeparameter, der mindestens erforderlich ist, um auf den Rest der Typen zu schließen). Jetzt können Sie es so nennen:
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!");
Sie können zusätzliche Überladungen für Action<S>
und Expression<Action<S>>
in derselben Klasse haben. Für andere in Delegaten und Ausdrucksarten gebaut, werden Sie separate Klassen gerne schreiben müssen Lambda
, Lambda<S, T>
,Lambda<S, T, U>
usw.
Vorteil davon sehe ich gegenüber dem ursprünglichen Ansatz:
Eine Typspezifikation weniger (nur der formale Parameter muss angegeben werden).
Dies gibt Ihnen die Freiheit, es gegen jeden zu verwenden Func<int, T>
, nicht nur wenn T
es gesagt wird string
, wie in Beispielen gezeigt.
Unterstützt Ausdrücke sofort. Bei dem früheren Ansatz müssen Sie erneut Typen angeben, z.
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!");
für Ausdrücke.
Das Erweitern der Klasse für andere Delegatentypen (und Ausdruckstypen) ist ähnlich umständlich wie oben.
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 meinem Ansatz müssen Sie Typen nur einmal deklarieren (das auch eins weniger für Func
s).
Eine andere Möglichkeit, Andreys Antwort umzusetzen, besteht darin, nicht vollständig generisch zu werden
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;
}
Die Dinge reduzieren sich also auf:
var l = Lambda<int>.Expression;
var e1 = l(x => x.ToString());
var e2 = l(x => "Hello!");
var e3 = l(x => x + x);
Das ist noch weniger Tippen, aber Sie verlieren bestimmte Typensicherheit, und imo, das ist es nicht wert.