protected object Visit(BinaryExpression expression) { switch (expression.NodeType) { case ExpressionType.OrElse: { var left = this.Visit(expression.Left); if ((bool)left) { return(true); } return((bool)this.Visit(expression.Right)); } case ExpressionType.AndAlso: { var left = this.Visit(expression.Left); if (!(bool)left) { return(false); } return((bool)this.Visit(expression.Right)); } case ExpressionType.Or: { var left = (long)Convert.ChangeType(this.Visit(expression.Left), typeof(long)); var right = (long)Convert.ChangeType(this.Visit(expression.Right), typeof(long)); return(Convert.ChangeType(left | right, expression.Type)); } case ExpressionType.And: { var left = (long)Convert.ChangeType(this.Visit(expression.Left), typeof(long)); var right = (long)Convert.ChangeType(this.Visit(expression.Right), typeof(long)); return(Convert.ChangeType(left & right, expression.Type)); } case ExpressionType.ExclusiveOr: { var left = (long)Convert.ChangeType(this.Visit(expression.Left), typeof(long)); var right = (long)Convert.ChangeType(this.Visit(expression.Right), typeof(long)); return(Convert.ChangeType(left ^ right, expression.Type)); } case ExpressionType.Equal: case ExpressionType.NotEqual: { if (expression.Type == typeof(bool)) { var left = this.Visit(expression.Left); if (left == InterpretFailed) { return(InterpretFailed); } var right = this.Visit(expression.Right); if (right == InterpretFailed) { return(InterpretFailed); } if (left == right) { return(expression.NodeType == ExpressionType.Equal); } if (left is short && right is short) { return(((short)left == (short)right) && expression.NodeType == ExpressionType.Equal); } else if (left is int && right is int) { return((int)left == (int)right && expression.NodeType == ExpressionType.Equal); } else if (left is long && right is long) { return((long)left == (long)right && expression.NodeType == ExpressionType.Equal); } else if (left is string && right is string) { return((string)left == (string)right && expression.NodeType == ExpressionType.Equal); } else if (expression.Left.Type == typeof(object) && expression.Right.Type == typeof(object)) { return(EqualityComparer <object> .Default.Equals(left, right)); } return(InterpretFailed); } return(InterpretFailed); } case ExpressionType.Add: case ExpressionType.Subtract: case ExpressionType.Multiply: case ExpressionType.Divide: { var left = this.Visit(expression.Left); if (left == InterpretFailed) { return(InterpretFailed); } var right = this.Visit(expression.Right); if (right == InterpretFailed) { return(InterpretFailed); } Type type = null; if (expression.Left.Type == typeof(string) || expression.Right.Type == typeof(string)) { type = typeof(string); left = Convert.ChangeType(left, typeof(string)); right = Convert.ChangeType(right, typeof(string)); } else if (expression.Left.Type == typeof(decimal) || expression.Right.Type == typeof(decimal)) { type = typeof(decimal); left = Convert.ChangeType(left, typeof(decimal)); right = Convert.ChangeType(right, typeof(decimal)); } else if (expression.Left.Type == typeof(double) || expression.Right.Type == typeof(double)) { type = typeof(double); left = Convert.ChangeType(left, typeof(double)); right = Convert.ChangeType(right, typeof(double)); } else if (expression.Left.Type == typeof(float) || expression.Right.Type == typeof(float)) { type = typeof(float); left = Convert.ChangeType(left, typeof(float)); right = Convert.ChangeType(right, typeof(float)); } else if (expression.Left.Type == typeof(long) || expression.Right.Type == typeof(long)) { type = typeof(long); left = Convert.ChangeType(left, typeof(long)); right = Convert.ChangeType(right, typeof(long)); } else if (expression.Left.Type == typeof(uint) || expression.Right.Type == typeof(uint)) { if (expression.Left.Type == typeof(uint) && expression.Right.Type == typeof(uint)) { type = typeof(uint); left = Convert.ChangeType(left, typeof(uint)); right = Convert.ChangeType(right, typeof(uint)); } else { type = typeof(long); left = Convert.ChangeType(left, typeof(long)); right = Convert.ChangeType(right, typeof(long)); } } else if (expression.Left.Type == typeof(int) || expression.Right.Type == typeof(int)) { type = typeof(int); left = Convert.ChangeType(left, typeof(int)); right = Convert.ChangeType(right, typeof(int)); } else if (expression.Left.Type == typeof(ushort) || expression.Right.Type == typeof(ushort)) { if (expression.Left.Type == typeof(ushort) && expression.Right.Type == typeof(ushort)) { type = typeof(ushort); left = Convert.ChangeType(left, typeof(ushort)); right = Convert.ChangeType(right, typeof(ushort)); } else { type = typeof(int); left = Convert.ChangeType(left, typeof(int)); right = Convert.ChangeType(right, typeof(int)); } } else if (expression.Left.Type == typeof(short) || expression.Right.Type == typeof(short)) { type = typeof(short); left = Convert.ChangeType(left, typeof(short)); right = Convert.ChangeType(right, typeof(short)); } else if (expression.Left.Type == typeof(byte) || expression.Right.Type == typeof(byte)) { type = typeof(byte); left = Convert.ChangeType(left, typeof(byte)); right = Convert.ChangeType(right, typeof(byte)); } else if (expression.Left.Type == typeof(sbyte) || expression.Right.Type == typeof(sbyte)) { type = typeof(int); left = Convert.ChangeType(left, typeof(int)); right = Convert.ChangeType(right, typeof(int)); } else if (expression.Left.Type == typeof(byte) || expression.Right.Type == typeof(byte)) { type = typeof(int); left = Convert.ChangeType(left, typeof(int)); right = Convert.ChangeType(right, typeof(int)); } if (type == null) { return(InterpretFailed); } Func <object, object, object> func = null; switch (expression.NodeType) { case ExpressionType.Add: func = BinaryOperations.GetAddFunc(type); break; case ExpressionType.Subtract: func = BinaryOperations.GetSubtractFunc(type); break; case ExpressionType.Multiply: func = BinaryOperations.GetMultiplyFunc(type); break; case ExpressionType.Divide: func = BinaryOperations.GetDivideFunc(type); break; } if (func != null) { return(func(left, right)); } return(InterpretFailed); } default: return(InterpretFailed); } }