Beispiel #1
0
        // Creates the three canonical null guard conditions.
        private static Expression CreateNullGuardBlockExpression <TProperty>(AutoEqualityPropertyContext context, LabelTarget labelTarget)
        {
            var areEqualExpression    = CreateIfThenExpression <TProperty, bool>(context, labelTarget, (left, right) => ReferenceEquals(left, right), true);
            var leftIsNullExpression  = CreateIfThenExpression <TProperty, bool>(context, labelTarget, (left, right) => ReferenceEquals(left, null), false);
            var rightIsNullExpression = CreateIfThenExpression <TProperty, bool>(context, labelTarget, (left, right) => ReferenceEquals(left, null), false);

            return(Expression.Block(
                       areEqualExpression,
                       leftIsNullExpression,
                       rightIsNullExpression
                       ));
        }
Beispiel #2
0
        public static Expression CreateEqualsExpression <TProperty>(AutoEqualityPropertyContext context)
        {
            var labelTarget = Expression.Label(typeof(bool));

            var nullGuardBlockExpression = CreateNullGuardBlockExpression <TProperty>(context, labelTarget);
            var equalsMethodExpression   = CreateEqualsMethodExpression <TProperty>(context);

            return(Expression.Block(new[]
            {
                nullGuardBlockExpression,
                Expression.Return(labelTarget, equalsMethodExpression),
                Expression.Label(labelTarget, defaultValue: Expression.Constant(false))
            }));
        }
Beispiel #3
0
        private static Expression CreateIfThenExpression <TProperty, TResult>(AutoEqualityPropertyContext context, LabelTarget labelTarget, Func <TProperty, TProperty, bool> referenceEquals, TResult result)
        {
            // Let the compiler create this expression for us.
            var referenceEquasExpression = (Expression <Func <TProperty, TProperty, bool> >)((left, right) => referenceEquals(left, right));

            var referenceEquasInvokeExpression = Expression.Invoke(
                referenceEquasExpression,
                Expression.Property(context.LeftParameter, context.Property),
                Expression.Property(context.RightParameter, context.Property)
                );

            return(Expression.IfThen(
                       referenceEquasInvokeExpression,
                       Expression.Return(labelTarget, Expression.Constant(result))
                       ));
        }
Beispiel #4
0
        // The 'rightParameter' argument is not used but by having the same signature for both methods allows for a few optimizations in other places.
        public static Expression CreateGetHashCodeExpression <TProperty>(AutoEqualityPropertyContext context)
        {
            if (HasDefaultComparer(context.Property.PropertyType))
            {
                // Short-cut to have compiler write this expression for us.
                //var getHashCodeFunc = (Expression<Func<TProperty, int>>)((obj) => ReferenceEquals(obj, null) ? 0 : GetComparer<TProperty>(context.Attribute).GetHashCode(obj));
                var getHashCodeFunc = (Expression <Func <TProperty, int> >)((obj) => GetComparer <TProperty>(context.Attribute).GetHashCode(obj));

                return(Expression.Invoke(
                           getHashCodeFunc,
                           Expression.Property(context.LeftParameter, context.Property)
                           ));
            }
            else
            {
                // Call the instance 'GetHashCode' method by default.

                var labelTarget = Expression.Label(typeof(int));

                //var getHashCodeNullGuardExpression = CreateGetHashCodeNullGuardExpression<TProperty>(context, labelTarget);
                //var getHashCodeMethod = context.Property.PropertyType.GetMethod(nameof(GetHashCode));

                var getHashCodeFunc = (Expression <Func <TProperty, int> >)((obj) => ReferenceEquals(obj, null) ? 0 : obj.GetHashCode());

                return(Expression.Invoke(
                           getHashCodeFunc,
                           Expression.Property(context.LeftParameter, context.Property)
                           ));
            }

            // ReSharper disable once AssignNullToNotNullAttribute - getHashCodeMethod is never null
            //var getHashCodeExpression = Expression.Call(
            //    Expression.Property(context.LeftParameter, context.Property),
            //    getHashCodeMethod
            //);

            //return Expression.Block(new[]
            //{
            //    getHashCodeNullGuardExpression,
            //    Expression.Return(labelTarget, getHashCodeExpression),
            //    Expression.Label(labelTarget, defaultValue: Expression.Constant(0))
            //});
        }
Beispiel #5
0
        private static Expression CreateEqualsMethodExpression <TProperty>(AutoEqualityPropertyContext context)
        {
            if (HasDefaultComparer(context.Property.PropertyType))
            {
                // Short-cut to have compiler write this expression for us.
                var equalsFunc = (Expression <Func <TProperty, TProperty, bool> >)((x, y) => GetComparer <TProperty>(context.Attribute).Equals(x, y));

                return(Expression.Invoke(
                           equalsFunc,
                           Expression.Property(context.LeftParameter, context.Property),
                           Expression.Property(context.RightParameter, context.Property)
                           ));
            }

            var equalsMethod = GetEqualsMethod(context.Property.PropertyType);

            return(Expression.Call(
                       Expression.Property(context.LeftParameter, context.Property),
                       equalsMethod,
                       Expression.Property(context.RightParameter, context.Property)
                       ));
        }
Beispiel #6
0
        private static Expression CreateGetHashCodeNullGuardExpression <TProperty>(AutoEqualityPropertyContext context, LabelTarget labelTarget)
        {
            var propertyIsNullExpression = CreateIfThenExpression <TProperty, int>(labelTarget, (left, right) => ReferenceEquals(left, right), context.LeftParameter, Expression.Constant(null, typeof(TProperty)), 0);

            return(Expression.Block(propertyIsNullExpression));
        }