@Andrey Naumovの答えに基づいてこれを構築しようとしました。これはわずかな改善かもしれません。
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>
など
これの利点は、元のアプローチよりも優れています。
型指定が1つ少なくなります(仮パラメーターのみを指定する必要があります)。
これにより、例に示すように、と言う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());
私のアプローチでは、型を1回だけ宣言する必要があります(Func
sの場合は1つ少なくなります)。
Andreyの答えを実装するもう1つの方法は、完全に一般的ではないようなものです
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);
これはタイピングがさらに少なくなりますが、特定のタイプセーフを失うので、これは価値がありません。