When we compare two objects of the same class in c# which is generated from a proto file, we can use Equals() since grpc protobuf overwrites Equals() for us to compare each fields.
However, for float and double fields, there's ProtobufEqualityComparers like this:
/// <summary>
/// Provides a central place to implement equality comparisons, primarily for bitwise float/double equality.
/// </summary>
public static class ProtobufEqualityComparers
{
/// <summary>
/// Returns an equality comparer for <typeparamref name="T" /> suitable for Protobuf equality comparisons.
/// This is usually just the default equality comparer for the type, but floating point numbers are compared
/// bitwise.
/// </summary>
/// <typeparam name="T">The type of equality comparer to return.</typeparam>
/// <returns>The equality comparer.</returns>
public static EqualityComparer<T> GetEqualityComparer<T>()
{
if (typeof (T) == typeof (double))
return (EqualityComparer<T>) ProtobufEqualityComparers.BitwiseDoubleEqualityComparer;
if (typeof (T) == typeof (float))
return (EqualityComparer<T>) ProtobufEqualityComparers.BitwiseSingleEqualityComparer;
if (typeof (T) == typeof (double?))
return (EqualityComparer<T>) ProtobufEqualityComparers.BitwiseNullableDoubleEqualityComparer;
return !(typeof (T) == typeof (float?)) ? EqualityComparer<T>.Default : (EqualityComparer<T>) ProtobufEqualityComparers.BitwiseNullableSingleEqualityComparer;
}
Specifically, there's a BitwiseDoubleEqualityComparer used for double values and BitwiseSingleEqualityComparer for float values.
Why do we need them?
I believe BitwiseDoubleEqualityComparer and BitwiseSingleEqualityComparer cannot solve precision issues when comparing floating numbers.