Bạn có thể sử dụng cây biểu thức làm trình tạo mã với mức trừu tượng cao hơn sau đó lắp ráp phát ra và nhanh hơn sau đó là CodeCompiler. Dưới đây là một số bằng chứng về khái niệm mà tôi đã sử dụng để thuyết phục nhóm của chúng tôi sử dụng chúng như một sự thay thế cho CodeCompiler.
[TestClass]
public class WhenINeedToAccessPropertiesByNameHavingATypeReference
{
public class SomeCategoryData
{
public DateTime CreatedDate { get; set; }
}
[TestMethod]
public void ICanDoThatWithAnExpressionAndItPerformsWell()
{
// INIT
var someCategoryData =
Enumerable.Range(1970, 100).Select(year =>
new SomeCategoryData { CreatedDate = new DateTime(year, 1, 1) }).Cast<object>();
var t = typeof(SomeCategoryData); // or it can be: t = someCategoryData.First().GetType();
var compiled = Stopwatch.StartNew();
// ACT
var filter = AccessPropertyByNameInCompiledMannerSomehow(t, "CreatedDate");
// ASSERT
Trace.WriteLine(string.Format("compiled in: {0}", compiled.Elapsed));
Assert.IsTrue(compiled.ElapsedMilliseconds < 3, "compiles fast enough");
var executed = Stopwatch.StartNew();
// ACT
List<object> result = null;
for (var i = 0; i < 10000; i++)
{
result = someCategoryData.Where(d => filter(d, new DateTime(2000, 1, 1), new DateTime(2009, 1, 1)))
.ToList();
}
executed.Stop();
Trace.WriteLine(string.Format("executed in: {0}", executed.Elapsed));
// ASSERT
Assert.AreEqual(10, result.Count, "insure compiled code actually works");
Assert.IsTrue(executed.ElapsedMilliseconds < 300, "runs fast enough");
}
private static Func<object, DateTime, DateTime, bool>
AccessPropertyByNameInCompiledMannerSomehow(Type t, string fieldToFilterBy)
{
var objectParameter = Expression.Parameter(typeof(object), "p");
var instance = Expression.Convert(objectParameter, t);
var lower = Expression.Parameter(typeof(DateTime), "l");
var upper = Expression.Parameter(typeof(DateTime), "u");
var composite = Expression.Lambda<Func<object, DateTime, DateTime, bool>>(
Expression.And(
Expression.LessThanOrEqual(
lower,
Expression.PropertyOrField(instance, fieldToFilterBy)
),
Expression.GreaterThanOrEqual(
upper,
Expression.PropertyOrField(instance, fieldToFilterBy)
)
), objectParameter, lower, upper
);
return composite.Compile();
}
}
Nguồn
2009-10-07 18:29:41
http://stackoverflow.com/questions/403088/practical-use-of-expression-trees –