Skip to content

Commit

Permalink
Delete reflection-base ValueType.Equals implementation (dotnet#894)
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalStrehovsky authored Mar 31, 2021
1 parent 4ae6d03 commit 5711873
Show file tree
Hide file tree
Showing 3 changed files with 0 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ public abstract class ReflectionExecutionDomainCallbacks
public abstract MethodBase GetMethodBaseFromStartAddressIfAvailable(IntPtr methodStartAddress);
public abstract Assembly GetAssemblyForHandle(RuntimeTypeHandle typeHandle);

#if PROJECTN
public abstract int ValueTypeGetHashCodeUsingReflection(object valueType);
public abstract bool ValueTypeEqualsUsingReflection(object left, object right);
#endif

/// <summary>
/// Retrieves the default value for a parameter of a method.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,6 @@ public abstract class ValueType
return this.GetType().ToString();
}

#if PROJECTN
public override bool Equals([NotNullWhen(true)] object? obj)
{
return RuntimeAugments.Callbacks.ValueTypeEqualsUsingReflection(this, obj);
}

public override int GetHashCode()
{
return RuntimeAugments.Callbacks.ValueTypeGetHashCodeUsingReflection(this);
}
#else
private const int UseFastHelper = -1;
private const int GetNumFields = -1;

Expand Down Expand Up @@ -197,6 +186,5 @@ private int RegularGetValueTypeHashCode(EETypePtr type, ref byte data, int numFi

return hashCode;
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -118,106 +118,6 @@ public sealed override IntPtr TryGetStaticClassConstructionContext(RuntimeTypeHa
return _executionEnvironment.TryGetStaticClassConstructionContext(runtimeTypeHandle);
}

/// <summary>
/// Compares FieldInfos, sorting by name.
/// </summary>
private class FieldInfoNameComparer : IComparer<FieldInfo>
{
private static FieldInfoNameComparer s_instance = new FieldInfoNameComparer();
public static FieldInfoNameComparer Instance
{
get
{
return s_instance;
}
}

public int Compare(FieldInfo x, FieldInfo y)
{
return x.Name.CompareTo(y.Name);
}
}

#if PROJECTN
/// <summary>
/// Reflection-based implementation of ValueType.GetHashCode. Matches the implementation created by the ValueTypeTransform.
/// </summary>
/// <param name="valueType">Boxed value type</param>
/// <returns>Hash code for the value type</returns>
public sealed override int ValueTypeGetHashCodeUsingReflection(object valueType)
{
// The algorithm is to use the hash of the first non-null instance field sorted by name.
List<FieldInfo> sortedFilteredFields = new List<FieldInfo>();
foreach (FieldInfo field in valueType.GetType().GetTypeInfo().DeclaredFields)
{
if (field.IsStatic)
{
continue;
}

sortedFilteredFields.Add(field);
}
sortedFilteredFields.Sort(FieldInfoNameComparer.Instance);

foreach (FieldInfo field in sortedFilteredFields)
{
object fieldValue = field.GetValue(valueType);
if (fieldValue != null)
{
return fieldValue.GetHashCode();
}
}

// Fallback path if no non-null instance field. The desktop hashes the GetType() object, but this seems like a lot of effort
// for a corner case - let's wait and see if we really need that.
return 1;
}

/// <summary>
/// Reflection-based implementation of ValueType.Equals. Matches the implementation created by the ValueTypeTransform.
/// </summary>
/// <param name="left">Boxed 'this' value type</param>
/// <param name="right">Boxed 'that' value type</param>
/// <returns>True if all nonstatic fields of the objects are equal</returns>
public sealed override bool ValueTypeEqualsUsingReflection(object left, object right)
{
if (right == null)
{
return false;
}

if (left.GetType() != right.GetType())
{
return false;
}

foreach (FieldInfo field in left.GetType().GetTypeInfo().DeclaredFields)
{
if (field.IsStatic)
{
continue;
}

object leftField = field.GetValue(left);
object rightField = field.GetValue(right);

if (leftField == null)
{
if (rightField != null)
{
return false;
}
}
else if (!leftField.Equals(rightField))
{
return false;
}
}

return true;
}
#endif

/// <summary>
/// Retrieves the default value for a parameter of a method.
/// </summary>
Expand Down

0 comments on commit 5711873

Please sign in to comment.