Sie können Ausdrucksbaum als Code-Generator mit einer höheren Abstraktionsebene dann Assembly emit und schneller als CodeCompiler verwenden. Hier ist ein Beweis für das Konzept, das ich verwendet habe, um unser Team davon zu überzeugen, sie als Ersatz für CodeCompiler zu verwenden.
[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();
}
}
http://stackoverflow.com/questions/403088/practical-use-of-expression-trees –