ReferenceNotEqual() public static method

Creates a BinaryExpression that represents a reference inequality comparison.
public static ReferenceNotEqual ( Expression left, Expression right ) : BinaryExpression
left Expression An to set the property equal to.
right Expression An to set the property equal to.
return BinaryExpression
Ejemplo n.º 1
0
        public void ReferenceNotEquals()
        {
            var expected =
                LinqExpression.ReferenceNotEqual(
                    LinqExpression.Parameter(
                        typeof(object)),
                    LinqExpression.Parameter(
                        typeof(object)));

            var actual = $@"
@prefix : <http://example.com/> .

:s
    a :ReferenceNotEqual ;
    :binaryLeft [
        :parameterType [
            :typeName ""System.Object"" ;
        ]
    ] ;
    :binaryRight [
        :parameterType [
            :typeName ""System.Object"" ;
        ] ;
    ] ;
.
";

            ShouldBe(actual, expected);
        }
        // Helper that is used when re-eval of LHS is safe.
        private Expression ByValParameterTypeEqual(ParameterExpression value)
        {
            Expression getType = Expression.Call(value, typeof(object).GetMethod("GetType"));

            // In remoting scenarios, obj.GetType() can return an interface.
            // But JIT32's optimized "obj.GetType() == typeof(ISomething)" codegen,
            // causing it to always return false.
            // We workaround this optimization by generating different, less optimal IL
            // if TypeOperand is an interface.
            if (_typeOperand.GetTypeInfo().IsInterface)
            {
                var temp = Expression.Parameter(typeof(Type));
                getType = Expression.Block(new[] { temp }, Expression.Assign(temp, getType), temp);
            }

            // We use reference equality when comparing to null for correctness
            // (don't invoke a user defined operator), and reference equality
            // on types for performance (so the JIT can optimize the IL).
            return(Expression.AndAlso(
                       Expression.ReferenceNotEqual(value, Expression.Constant(null)),
                       Expression.ReferenceEqual(
                           getType,
                           Expression.Constant(_typeOperand.GetNonNullableType(), typeof(Type))
                           )
                       ));
        }
        internal Expression ReduceTypeEqual()
        {
            Type cType = Expression.Type;

            // For value types (including Void, but not nullables), we can
            // determine the result now
            if (cType.GetTypeInfo().IsValueType&& !cType.IsNullableType())
            {
                return(Expression.Block(Expression, Expression.Constant(cType == _typeOperand.GetNonNullableType())));
            }

            // Can check the value right now for constants.
            if (Expression.NodeType == ExpressionType.Constant)
            {
                return(ReduceConstantTypeEqual());
            }

            // If the expression type is a sealed reference type or a nullable
            // type, it will match if the value is not null and the type operand
            // either matches or one is a nullable type while the other is its
            // type argument (T to the other's T?).
            if (cType.GetTypeInfo().IsSealed)
            {
                if (cType.GetNonNullableType() != _typeOperand.GetNonNullableType())
                {
                    return(Expression.Block(Expression, Expression.Constant(false)));
                }
                else if (cType.IsNullableType())
                {
                    return(Expression.NotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
                else
                {
                    return(Expression.ReferenceNotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
            }

            Debug.Assert(TypeUtils.AreReferenceAssignable(typeof(object), Expression.Type), "Expecting reference types only after this point.");

            // expression is a ByVal parameter. Can safely reevaluate.
            var parameter = Expression as ParameterExpression;

            if (parameter != null && !parameter.IsByRef)
            {
                return(ByValParameterTypeEqual(parameter));
            }

            // Create a temp so we only evaluate the left side once
            parameter = Expression.Parameter(typeof(object));

            return(Expression.Block(
                       new[] { parameter },
                       Expression.Assign(parameter, Expression),
                       ByValParameterTypeEqual(parameter)
                       ));
        }
Ejemplo n.º 4
0
        internal Expression ReduceTypeEqual()
        {
            Type cType = Expression.Type;

            // For value types (including Void, but not nullables), we can
            // determine the result now
            if (cType.GetTypeInfo().IsValueType&& !cType.IsNullableType())
            {
                return(Expression.Block(Expression, Expression.Constant(cType == _typeOperand.GetNonNullableType())));
            }

            // Can check the value right now for constants.
            if (Expression.NodeType == ExpressionType.Constant)
            {
                return(ReduceConstantTypeEqual());
            }

            // If the operand type is a sealed reference type or a nullable
            // type, it will match if value is not null
            if (cType.GetTypeInfo().IsSealed&& (cType == _typeOperand))
            {
                if (cType.IsNullableType())
                {
                    return(Expression.NotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
                else
                {
                    return(Expression.ReferenceNotEqual(Expression, Expression.Constant(null, Expression.Type)));
                }
            }

            // expression is a ByVal parameter. Can safely reevaluate.
            var parameter = Expression as ParameterExpression;

            if (parameter != null && !parameter.IsByRef)
            {
                return(ByValParameterTypeEqual(parameter));
            }

            // Create a temp so we only evaluate the left side once
            parameter = Expression.Parameter(typeof(object));

            // Convert to object if necessary
            var expression = Expression;

            if (!TypeUtils.AreReferenceAssignable(typeof(object), expression.Type))
            {
                expression = Expression.Convert(expression, typeof(object));
            }

            return(Expression.Block(
                       new[] { parameter },
                       Expression.Assign(parameter, expression),
                       ByValParameterTypeEqual(parameter)
                       ));
        }
        public void ReferenceNotEqual()
        {
            var expression =
                LinqExpression.ReferenceNotEqual(
                    LinqExpression.Parameter(
                        typeof(object)),
                    LinqExpression.Parameter(
                        typeof(object)));

            ShouldRoundrip(expression);
        }
Ejemplo n.º 6
0
 public BinaryExpression Update(Expression left, LambdaExpression conversion, Expression right)
 {
     if (((left == this.Left) && (right == this.Right)) && (conversion == this.Conversion))
     {
         return(this);
     }
     if (!this.IsReferenceComparison)
     {
         return(Expression.MakeBinary(this.NodeType, left, right, this.IsLiftedToNull, this.Method, conversion));
     }
     if (this.NodeType == ExpressionType.Equal)
     {
         return(Expression.ReferenceEqual(left, right));
     }
     return(Expression.ReferenceNotEqual(left, right));
 }
Ejemplo n.º 7
0
        private static Func <Expression, IList <ParameterExpression>, Expr> CreateCheckExprFunc(LambdaExpression checkExpr)
        {
            return
                ((valueVar, additionalParams) =>
            {
                // Prepare Length/Count expression
                var lengthExpr = Expr.Property(valueVar, valueVar.Type.HasProperty("Length") ? "Length" : "Count");

                // Use it in checkExpr
                var body = checkExpr.ReplaceParams(additionalParams).Replace(checkExpr.Parameters[0], lengthExpr);

                // Maybe add null check
                if (!valueVar.Type.IsValueType)
                {
                    body = Expr.AndAlso(Expr.ReferenceNotEqual(valueVar, Expr.Constant(null)), body);
                }

                return body;
            });
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Creates verifier which checks object public properties.
        /// </summary>
        /// <typeparam name="TVerifier">Verifier type.</typeparam>
        /// <param name="propertyFilter">Object public properties filter; can be null to generate code for all the properties.</param>
        /// <param name="checkExprFunc">Function which generates property value check expression (if returns true then check is failed).
        /// Function obtains variable which holds property value and additional arguments.</param>
        /// <param name="createExceptionExpr">New exception creation expression used when check is failed.</param>
        /// <returns>Verifier instance.</returns>
        public static TVerifier Create <TVerifier>(
            Func <Type, bool> propertyFilter,
            Func <Expression, IList <ParameterExpression>, Expr> checkExprFunc,
            LambdaExpression createExceptionExpr) where TVerifier : class
        {
            VerifyUtil.NotNull(checkExprFunc, "checkExprFunc");
            VerifyUtil.NotNull(createExceptionExpr, "createExceptionExpr");

            Type argumentsType = typeof(TVerifier).GetGenericArguments()[0];
            Type type          = argumentsType.GetGenericArguments()[0];

            // Prepare lambda action parameters - first is Argument<T>, others are additionalParamTypes
            var objectParam      = Expr.Parameter(argumentsType);
            var objectVar        = Expr.Parameter(type);
            var genericArguments = typeof(TVerifier).GetGenericArguments();
            var additionalParams = genericArguments.Skip(1).Take(genericArguments.Length - 2).Select(Expr.Parameter).ToList();

            Expr lambdaBody;

            if (type.IsAnonymous())
            {
                // Take createExceptionExpr lambda, extract first parameter from it and replace additional parameters in body
                var exceptionNameParam   = createExceptionExpr.Parameters[0];
                var exceptionObjectParam = createExceptionExpr.Parameters[1];
                var exceptionBody        = createExceptionExpr.ReplaceParams(additionalParams);

                // Obtain type public properties to check
                propertyFilter = propertyFilter ?? (_ => true);
                var properties = type.GetProperties().OrderBy(pi => pi.Name).Where(pi => propertyFilter(pi.PropertyType));

                // Obtain argument values from fields since it's faster
                var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(fi => fi.Name).Where(fi => propertyFilter(fi.FieldType)).ToList();

                // Generate "if (checkExpr) then throw createExceptionExpr;" for each of the properties
                var propertyChecks = properties
                                     .Select(
                    (pi, i) =>
                {
                    var valueVar = Expr.Field(objectVar, fields[i]);
                    return((Expr)Expr.IfThen(
                               checkExprFunc(valueVar, additionalParams),
                               Expr.Throw(
                                   exceptionBody
                                   .Replace(exceptionNameParam, Expr.Constant(pi.Name))
                                   .Replace(exceptionObjectParam, valueVar.ConvertIfNeeded(exceptionObjectParam.Type)))));
                })
                                     .ToList();

                // Prepare null check - if null is supplied then all checks are passed since nothing to check
                var checksBody = propertyChecks.Any()
                                        ? Expr.IfThen(
                    Expr.ReferenceNotEqual(objectVar, Expr.Constant(null, type)),
                    propertyChecks.Count > 1 ? Expr.Block(propertyChecks) : propertyChecks[0])
                                        : null;

                lambdaBody = propertyChecks.Any()
                                        ? (Expr)Expr.Block(
                    new[] { objectVar },
                    new Expr[] { Expr.Assign(objectVar, Expr.Field(objectParam, "Holder")) }
                    .Concat(new[] { checksBody })
                    .Concat(new[] { objectParam }))
                                        : objectParam;
            }
            else
            {
                // Not anonymous type - throw an exception
                lambdaBody = Expr.Block(
                    Expr.Throw(
                        Expr.New(
                            VerifyArgsExceptionCtor,
                            Expr.Constant(string.Format(ErrorMessages.NotAnonymousType, type)))),
                    objectParam);
            }

            // Pull it all together, execute checks only if supplied object is not null
            var lambda = Expr.Lambda <TVerifier>(
                lambdaBody,
                new[] { objectParam }.Concat(additionalParams));

            return(lambda.Compile());
        }