Esempio n. 1
0
        /// <summary>
        /// Returns true if two objects match equality
        /// </summary>
        /// <param name="typeSupport">The extended type for the left object</param>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <returns></returns>
        private bool CompareForObjectEquality(ExtendedType typeSupport, object left, object right)
        {
            // order of precedence: IEquatable => Equals => (==)
            // if the object implements IEquatable, use it
            var hasIEquatable = typeSupport.Implements(typeof(IEquatable <>));

            if (hasIEquatable)
            {
                var equatableMethod = typeSupport.Methods?.FirstOrDefault(x => x.Name == "Equals" && x.Parameters.Any(y => y.ParameterType == typeSupport.Type));
                var isEquatable     = (bool)equatableMethod?.MethodInfo.Invoke(left, new object[] { right }) == true;
                if (isEquatable)
                {
                    return(true); // no differences found
                }
            }
            else
            {
                // if the object overrides Equals(), use it
                var hasEqualsOverride = typeSupport.Methods?.Any(x => x.Name == "Equals" && x.IsOverride) == true;
                if (hasEqualsOverride)
                {
                    if (left.Equals(right))
                    {
                        return(true); // no differences found
                    }
                }
                else
                {
                    // if the object overrides the equality operator (==), use it
                    var hasEqualityOperator = typeSupport.Methods?.Any(x => x.Name == "op_Equality" && x.IsOperatorOverload) == true;
                    if (hasEqualityOperator)
                    {
                        var operatorMethod = typeSupport.Methods?.FirstOrDefault(x => x.Name == "op_Equality" && x.Parameters.All(y => y.ParameterType == typeSupport.Type));
                        var isEqual        = (bool)operatorMethod?.MethodInfo.Invoke(left, new object[] { left, right }) == true;
                        if (isEqual)
                        {
                            return(true); // no differences found
                        }
                    }
                }
            }
            return(false);
        }