Yani, istediğiniz Sonra
Func<Func<DateTime,string>, DateTime, string> requiredLambda = (f, dt) =>
{
var formattedDate = f.Invoke(dt);
/**
* The logic is not important here - what is important is that I
* am using the result of the executed lambda expression.
* */
var builder = new StringBuilder();
builder.Append(formattedDate);
builder.Append(" Hello!");
return builder.ToString();
};
Girdinizin ifade var Geçirilen işlevinizi kullanan bir lambda (ifade) oluşturmak ve çevresinde ek bir çalışma yapmak. Yani aslında bu işlevi bir ifadenin içinde kullanmak istersiniz. Bu noktada
, beni bile ifadeleri kullanmayın önermek için izin verir. Sadece bir
Func<DateTime, string>
parametresini alan ve bunu işlemek için kullanan bir işlev oluşturabilirsiniz. Ancak, gerçekten bir şey için ifadeye ihtiyacınız varsa, nasıl bir tane inşa edeceğimi açıklamaya çalışacağım. Bu örnek için
, ben bu işlevi oluşturacaksınız: Gördüğünüz gibi, o zaman
DateTime
nesneyi oluşturur ve ardından fonksiyonu ve bunu geçiren bir
Func<int, int, string>
oluşturmak için gidiyorum
string MonthAndDayToString (int month, int day)
{
return "'" + formattingFunction(new DateTime(2013, month, day)) + "'"
}
sonucu daha da değiştirir.
Func<DateTime, string> formatting = dt => (...) // as above
// define parameters for the lambda expression
ParameterExpression monthParam = Expression.Parameter(typeof(int));
ParameterExpression dayParam = Expression.Parameter(typeof(int));
// look up DateTime constructor
ConstructorInfo ci = typeof(DateTime).GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int) });
// look up string.Concat
MethodInfo concat = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string), typeof(string) });
// inner call: formatting(new DateTime(2013, month, day))
var call = Expression.Call(formatting.Method, Expression.New(ci, Expression.Constant(2013), monthParam, dayParam));
// concat: "'" + call + "'"
var expr = Expression.Call(concat, Expression.Constant("'"), call, Expression.Constant("'"));
// create the final lambda: (int, int) => expr
var lambda = Expression.Lambda<Func<int, int, string>>(expr, new ParameterExpression[] { monthParam, dayParam });
// compile and execute
Func<int, int, string> func = lambda.Compile();
Console.WriteLine(func(2, 1)); // '01.02.2013 Hello!'
Console.WriteLine(func(11, 26)); // '26.11.2013 Hello!'
Alex'in’cevabını baktıktan sonra ben sorunuzu yanlış ve ne yaptığınızı tersini çözmeye çalıştı gibi görünüyor. Ama aslında yapmaya çalıştıkları şeye bunu değiştirmek için hiç de farklı değil:
Func<DateTime, string> formatting = dt => dt.ToShortDateString();
ParameterExpression param = Expression.Parameter(typeof(DateTime));
MethodInfo concat = typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string), typeof(string) });
var call = Expression.Call(formatting.Method, param);
var expr = Expression.Call(concat, Expression.Constant("'"), call, Expression.Constant(" Hello!'"));
var lambda = Expression.Lambda<Func<DateTime, string>>(expr, new ParameterExpression[] { param });
Func<DateTime, string> func = lambda.Compile();
Console.WriteLine(func(new DateTime(2013, 02, 01)));
Console.WriteLine(func(new DateTime(2013, 11, 26)));
Ama hala Func<DateTime, string>
ve DateTime
parametre alır normal bir fonksiyon korumak için çok daha kolay olacağını iddia ediyorum . Yani, 'un ifadeler gerçekten ifadelerine ihtiyaç duymadıkça, bunlardan kaçının.Seni hala düşünmüyorum Neden
gerçekten buna ifadeleri gerekir. Bu örneği ele alalım: Gördüğünüz gibi, bunu bir kez formatlama mantığı fonksiyonu inşa ediyorum
private Func<DateTime, string> formatting = dt => dt.ToShortDateString();
private Func<DateTime, string> formattingLogic = null;
public Func<DateTime, string> FormattingLogic
{
get
{
if (formattingLogic == null)
{
// some results from reflection
string word = "Hello";
string quote = "'";
formattingLogic = dt =>
{
StringBuilder str = new StringBuilder(quote);
str.Append(formatting(dt));
if (!string.IsNullOrWhiteSpace(word))
str.Append(" ").Append(word);
str.Append(quote);
return str.ToString();
};
}
return formattingLogic;
}
}
void Main()
{
Console.WriteLine(FormattingLogic(new DateTime(2013, 02, 01))); // '01.02.2013 Hello'
Console.WriteLine(FormattingLogic(new DateTime(2013, 11, 26))); // '26.11.2013 Hello'
}
, henüz set değil tembel zaman. Yansıma, işlevde bir yerlerde kullandığınız bazı değerleri almak için çalıştığında gerçekleşir. Fonksiyon bir lambda fonksiyonu olarak yaratıldıkça, lambda fonksiyonu içindeki yerel kapsamdan kullandığımız değişkenler otomatik olarak yakalanır ve kullanılabilir halde tutulur.
Elbette bunun yerine bir ifade olarak bunu oluşturabilir ve derlenmiş işlevi saklayabilirsiniz, ancak bunun böyle yapılmasının çok daha okunabilir ve sürdürülebilir olduğunu söyleyebilirim.
Anlamıyorum. İfade ağacının içinde neden formattingExpression.Compile() 'yi çağırmıyorsunuz? – svick