Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Jun 27th, 2012  |  syntax: None  |  size: 2.90 KB  |  hits: 8  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. public class Swapper
  2.     {
  3.         public static void Swap<T>(Expression<Func<T>> left, Expression<Func<T>> right)
  4.         {
  5.             var lvalue = left.Compile()();
  6.             var rvalue = right.Compile()();
  7.  
  8.             switch (left.Body.NodeType)
  9.             {
  10.                 case ExpressionType.ArrayIndex:
  11.                     var binaryExp = left.Body as BinaryExpression;
  12.                     AssignTo(rvalue, binaryExp);
  13.                     break;
  14.                 case ExpressionType.Call:
  15.                     var methodCall = left.Body as MethodCallExpression;
  16.                     AssignTo(rvalue, methodCall);
  17.                     break;
  18.                 default:
  19.                     AssignTo(left, rvalue);
  20.                     break;
  21.             }
  22.  
  23.             switch (right.Body.NodeType)
  24.             {
  25.                 case ExpressionType.ArrayIndex:
  26.                     var binaryExp = right.Body as BinaryExpression;
  27.                     AssignTo(lvalue, binaryExp);
  28.                     break;
  29.                 case ExpressionType.Call:
  30.                     var methodCall = right.Body as MethodCallExpression;
  31.                     AssignTo(lvalue, methodCall);
  32.                     break;
  33.                 default:
  34.                     AssignTo(right, lvalue);
  35.                     break;
  36.  
  37.             }
  38.  
  39.         }
  40.  
  41.         private static void AssignTo<T>(T value, MethodCallExpression methodCall)
  42.         {
  43.             var setter = GetSetMethodInfo(methodCall.Method.DeclaringType,methodCall.Method.Name);
  44.             Expression.Lambda<Action>(
  45.                 Expression.Call(methodCall.Object, setter, Join(methodCall.Arguments, Expression.Constant(value)))
  46.             ).Compile()();
  47.         }
  48.  
  49.         private static Expression[] Join(ReadOnlyCollection<Expression> args,Expression exp)
  50.         {
  51.             List<Expression> exps = new List<Expression>();
  52.             exps.AddRange(args);
  53.             exps.Add(exp);
  54.             return exps.ToArray();
  55.         }
  56.  
  57.         private static MethodInfo GetSetMethodInfo(Type target, string name)
  58.         {
  59.             var setName = Regex.Replace(name, "get", new MatchEvaluator((m) =>
  60.             {
  61.                 return m.Value.StartsWith("g")?"set":"Set";
  62.             })
  63.             ,RegexOptions.IgnoreCase);
  64.             var setter = target.GetMethod(setName);
  65.             if (null == setter)
  66.             {
  67.                 throw new Exception("can't find an expected method named:" + setName);
  68.             }
  69.             return setter;
  70.         }
  71.  
  72.         private static void AssignTo<T>(Expression<Func<T>> left, T value)
  73.         {
  74.             Expression.Lambda<Func<T>>(Expression.Assign(left.Body, Expression.Constant(value))).Compile()();
  75.         }
  76.  
  77.         private static void AssignTo<T>(T value, BinaryExpression binaryExp)
  78.         {
  79.             Expression.Lambda<Func<T>>(Expression.Assign(Expression.ArrayAccess(binaryExp.Left, binaryExp.Right), Expression.Constant(value))).Compile()();
  80.         }
  81.     }