Saya mencoba membangun ini berdasarkan jawaban @Andrey Naumov . Mungkin ini sedikit perbaikan.
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;
}
}
Di mana parameter tipe S
adalah parameter formal (parameter input, yang minimum diperlukan untuk menyimpulkan tipe lainnya). Sekarang Anda bisa menyebutnya seperti:
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!");
Anda dapat memiliki kelebihan beban tambahan untuk Action<S>
dan Expression<Action<S>>
serupa di kelas yang sama. Untuk lainnya dibangun dalam mendelegasikan dan ekspresi jenis, Anda akan harus menulis kelas terpisah seperti Lambda
, Lambda<S, T>
, Lambda<S, T, U>
dll
Keuntungan dari ini saya lihat dari pendekatan aslinya:
Satu spesifikasi tipe yang lebih sedikit (hanya parameter formal yang perlu ditentukan).
Yang memberi Anda kebebasan untuk menggunakannya terhadap apa pun Func<int, T>
, tidak hanya ketika T
dikatakan string
, seperti yang ditunjukkan dalam contoh.
Mendukung ekspresi langsung. Dalam pendekatan sebelumnya Anda harus menentukan tipe lagi, seperti:
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!");
untuk ekspresi.
Memperluas kelas untuk tipe delegasi (dan ekspresi) lain juga merepotkan seperti di atas.
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());
Dalam pendekatan saya, Anda harus mendeklarasikan tipe hanya sekali (itu terlalu satu kurang untuk Func
s).
Satu cara lain untuk mengimplementasikan jawaban Andrey adalah seperti tidak sepenuhnya generik
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;
}
Jadi hal-hal berkurang menjadi:
var l = Lambda<int>.Expression;
var e1 = l(x => x.ToString());
var e2 = l(x => "Hello!");
var e3 = l(x => x + x);
Itu bahkan lebih sedikit mengetik, tetapi Anda kehilangan keamanan jenis tertentu, dan imo, ini tidak sepadan.