[英]reflection v expression
我在看另一個問題 ,該問題表明Expression可以比預編譯快得多,因為它可以預編譯為IL。
我不太確定如何使用它。 這是在基類中用於值對象(在DDD意義上)使用的一些代碼,其基本思想是使用所有公共屬性的值來確定相等性,這是通過反射獲得的。 通過使用此基類,您無需為具有Value Object的子類實現相等性。
protected virtual bool HasSameObjectSignatureAs(BaseObject compareTo)
{
var signatureProperties = GetType().GetProperties();
foreach (var property in signatureProperties)
{
var valueOfThisObject = property.GetValue(this, null);
var valueOfCompareTo = property.GetValue(compareTo, null);
if (valueOfThisObject == null && valueOfCompareTo == null) {
continue;
}
if ((valueOfThisObject == null ^ valueOfCompareTo == null) ||
(!valueOfThisObject.Equals(valueOfCompareTo))) {
return false;
}
}
如何使用Expression重寫此代碼?
干杯,
Berryl
您可以通過為要比較的每個屬性構建一個嵌套的And
表達式來做到這一點:
protected Expression<Func<BaseObject, bool>> CreatePropertiesEqualExpression(BaseObject other)
{
if (! other.GetType().IsSubclassOf(this.GetType())) throw new ArgumentException();
var properties = this.GetType().GetProperties();
Expression trueExpr = Expression.Constant(true);
Expression thisExpr = Expression.Constant(this);
ParameterExpression paramExpr = Expression.Parameter(typeof(BaseObject), "compareTo");
Expression downCastExpr = Expression.Convert(paramExpr, other.GetType());
MethodInfo eqMethod = typeof(object).GetMethod("Equals", BindingFlags.Public | BindingFlags.Static);
Expression propCompExpr = properties.Aggregate(trueExpr, (expr, prop) =>
{
Expression thisPropExpr = Expression.Property(thisExpr, prop);
Expression compPropExpr = Expression.Property(downCastExpr, prop);
Expression eqExpr = Expression.Call(null, eqMethod, Expression.Convert(thisPropExpr, typeof(object)), Expression.Convert(compPropExpr, typeof(object)));
return Expression.And(expr, eqExpr);
});
return Expression.Lambda<Func<BaseObject, bool>>(propCompExpr, paramExpr);
}
然后可以像這樣使用它:
public class SubObject : BaseObject
{
public int Id { get; set; }
public string Name { get; set; }
private Func<BaseObject, bool> eqFunc;
public bool IsEqualTo(SubObject other)
{
if(this.eqFunc == null)
{
var compExpr = this.CreatePropertiesEqualExpression(other);
this.eqFunc = compExpr.Compile();
}
return this.eqFunc(other);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.