Linq表达访问者从对象类型A到对象类型B重写字段,其中字段是A上的数组,B上是字符串

时间:2017-08-11 18:24:11

标签: c# linq lambda linq-expressions

我有两个对象:

class A
{
    public string FieldA;
    public string FieldB;
    public string[] FieldC;
}

class B
{
    public string FieldA;
    public string FieldB;
    public string FieldC;
}

我有这个表达式访问者类,它将字段fieldA和fieldB的过滤器表达式从类型A 的对象重写为类型B 的对象。

private class AtoBModelRewriterVisitor : ExpressionVisitor
{
    protected override Expression VisitLambda<T>(Expression<T> node)
    {
         var lambda = (LambdaExpression)node;

         _LambdaStack.Push(
         lambda.Parameters.Select(parameter => objectAType == parameter.Type ? Expression.Parameter(objectBType) : parameter)
         .ToArray()
         );

         lambda = Expression.Lambda(
             this.Visit(lambda.Body),
             _LambdaStack.Pop()
         );

         return lambda;
    }
    protected override Expression VisitMember(MemberExpression node)
    {
         var memberExpression = (MemberExpression)node;

         var declaringType = memberExpression.Member.DeclaringType;
         var propertyName = memberExpression.Member.Name;

         if (objectAType == declaringType)
         {
             switch (propertyName)
             {
                 case "FieldA":
                 propertyName = "fieldA";
                 break;
                 case "FieldB":
                 propertyName = "fieldB";
                 break;              
             }

             memberExpression = Expression.Property(
                 this.Visit(memberExpression.Expression),
                 objectBType.GetProperty(propertyName)
             );
          }

          return memberExpression;
     }
     protected override Expression VisitParameter(ParameterExpression node)
     {
         node = (ParameterExpression)base.VisitParameter(node);
         if (objectAType == node.Type)
         {
             node = this._LambdaStack.Peek().Single(parameter => parameter.Type == objectBType);
         }
         return node;
     }

     #region [ Private ]

     private static Type objectAType = typeof(ObjectA);
     private static Type objectBType = typeof(ObjectB);
     private Stack<ParameterExpression[]> _LambdaStack = new Stack<ParameterExpression[]>();

     #endregion
 }

这完美无缺。现在我需要为fieldC / FieldC实现这个,它是objectA中的一个数组,但是是objectB中的一个字符串,所以我需要表达式来做类似的事情:

objectB.fieldC.Contains(objectA.FieldC[0])

objectB.fieldC.Contains(objectA.FieldC[N-1])

我很难写这篇文章。我感谢任何人都能提供的任何帮助。

0 个答案:

没有答案