Fix Attribute implementations of Equals and GetHashCode to properly deal with derived...
authorLlewellyn Pritchard <xacc.ide@gmail.com>
Thu, 20 Oct 2016 17:32:02 +0000 (19:32 +0200)
committerJan Kotas <jkotas@microsoft.com>
Thu, 20 Oct 2016 17:32:02 +0000 (10:32 -0700)
src/mscorlib/src/System/Attribute.cs

index 6475d8d..f21d527 100644 (file)
@@ -836,8 +836,8 @@ namespace System {
             if (obj == null)
                 return false;
 
-            RuntimeType thisType = (RuntimeType)this.GetType();
-            RuntimeType thatType = (RuntimeType)obj.GetType();
+            Type thisType = this.GetType();
+            Type thatType = obj.GetType();
 
             if (thatType != thisType)
                 return false;
@@ -845,18 +845,22 @@ namespace System {
             Object thisObj = this;
             Object thisResult, thatResult;
 
-            FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-
-            for (int i = 0; i < thisFields.Length; i++)
+            while (thisType != typeof(Attribute))
             {
-                // Visibility check and consistency check are not necessary.
-                thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
-                thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
+                FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
 
-                if (!AreFieldValuesEqual(thisResult, thatResult))
+                for (int i = 0; i < thisFields.Length; i++)
                 {
-                    return false;
+                    // Visibility check and consistency check are not necessary.
+                    thisResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(thisObj);
+                    thatResult = ((RtFieldInfo)thisFields[i]).UnsafeGetValue(obj);
+
+                    if (!AreFieldValuesEqual(thisResult, thatResult))
+                    {
+                        return false;
+                    }
                 }
+                thisType = thisType.BaseType;
             }
 
             return true;
@@ -914,27 +918,32 @@ namespace System {
         {
             Type type = GetType();
 
-            FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
-            Object vThis = null;
-
-            for (int i = 0; i < fields.Length; i++)
+            while (type != typeof(Attribute))
             {
-                // Visibility check and consistency check are not necessary.
-                Object fieldValue = ((RtFieldInfo)fields[i]).UnsafeGetValue(this);
+                FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
+                Object vThis = null;
 
-                // The hashcode of an array ignores the contents of the array, so it can produce 
-                // different hashcodes for arrays with the same contents.
-                // Since we do deep comparisons of arrays in Equals(), this means Equals and GetHashCode will
-                // be inconsistent for arrays. Therefore, we ignore hashes of arrays.
-                if (fieldValue != null && !fieldValue.GetType().IsArray)
-                    vThis = fieldValue;
+                for (int i = 0; i < fields.Length; i++)
+                {
+                    // Visibility check and consistency check are not necessary.
+                    Object fieldValue = ((RtFieldInfo)fields[i]).UnsafeGetValue(this);
+
+                    // The hashcode of an array ignores the contents of the array, so it can produce 
+                    // different hashcodes for arrays with the same contents.
+                    // Since we do deep comparisons of arrays in Equals(), this means Equals and GetHashCode will
+                    // be inconsistent for arrays. Therefore, we ignore hashes of arrays.
+                    if (fieldValue != null && !fieldValue.GetType().IsArray)
+                        vThis = fieldValue;
+
+                    if (vThis != null)
+                        break;
+                }
 
                 if (vThis != null)
-                    break;
-            }
+                    return vThis.GetHashCode();
 
-            if (vThis != null)
-                return vThis.GetHashCode();
+                type = type.BaseType;
+            }
 
             return type.GetHashCode();
         }