public static bool HasBuiltInEqualityOperator(Type left, Type right)
{
// If we have an interface and a reference type then we can do
// reference equality.
if (left.GetTypeInfo().IsInterface && !right.GetTypeInfo().IsValueType)
{
return true;
}
if (right.GetTypeInfo().IsInterface && !left.GetTypeInfo().IsValueType)
{
return true;
}
// If we have two reference types and one is assignable to the
// other then we can do reference equality.
if (!left.GetTypeInfo().IsValueType && !right.GetTypeInfo().IsValueType)
{
if (AreReferenceAssignable(left, right) || AreReferenceAssignable(right, left))
{
return true;
}
}
// Otherwise, if the types are not the same then we definitely
// do not have a built-in equality operator.
if (!AreEquivalent(left, right))
{
return false;
}
// We have two identical value types, modulo nullability. (If they were both the
// same reference type then we would have returned true earlier.)
Debug.Assert(left.GetTypeInfo().IsValueType);
// Equality between struct types is only defined for numerics, bools, enums,
// and their nullable equivalents.
Type nnType = GetNonNullableType(left);
if (nnType == typeof(bool) || IsNumeric(nnType) || nnType.GetTypeInfo().IsEnum)
{
return true;
}
return false;
}