Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Fix Attribute implementations of Equals and GetHashCode to properly d…
Browse files Browse the repository at this point in the history
…eal with derived types. #6232 (#6240)
  • Loading branch information
leppie authored and jkotas committed Oct 20, 2016
1 parent e66fca5 commit 9463e5d
Showing 1 changed file with 35 additions and 26 deletions.
61 changes: 35 additions & 26 deletions src/mscorlib/src/System/Attribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -836,27 +836,31 @@ public override bool Equals(Object obj)
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;

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;
Expand Down Expand Up @@ -914,27 +918,32 @@ public override int GetHashCode()
{
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();
}
Expand Down

0 comments on commit 9463e5d

Please sign in to comment.