Как я могу перегрузить Double.Equals () для моей структуры в C #? - PullRequest
0 голосов
/ 05 января 2019

В моей программе есть структура, представляющая меру, которую я хочу взаимозаменять с двойной.

Я реализовал это, и все, кажется, работает нормально, за исключением одного из моих тестов:

[Test]
public void TestMeasureDefaultConstructor()
{
    Measure m = new Measure();
    // These pass
    Assert.That(m.Equals(0), Is.True);
    Assert.That(0 == m, Is.True);
    Assert.That((double) m, Is.EqualTo(0));
    Assert.That((float) m, Is.EqualTo(0));
    Assert.That(0, Is.EqualTo(m));
    // The next two fail
    Assert.That(m, Is.EqualTo(0.0));
    Assert.That(0.0.Equals(m), Is.True);
}

Все работает до линии с Is.EqualTo (0.0).

Проверка двух строк, каждая из которых равна 0,0, равна m:

Message:   Expected: 0.0d
  But was:  MyCode.Model.Measure

(очевидно, что только первая не удалась, поэтому я должен поменять их местами, чтобы доказать это).

Я достаточно четко реализовал Equals для моего класса Measure, но я не могу понять, как расширить double.Equals, чтобы заставить работать последние два. Я провел много поисков, но продолжаю рассказывать, как реализовать Equals для моего класса, а не наоборот.

Вот мой класс, возможно, излишний после того, как попробовал все способы заставить его работать:

/// <summary>
/// The Measure class encapsulates the unit of measurement.
/// </summary>
public struct Measure
{
    #region Construction and destruction
    public Measure(double v)
    {
        Value = v;
    }
    #endregion
    #region Conversions
    public static implicit operator Measure(double v)
    {
        return new Measure(v);
    }

    public static implicit operator double(Measure m)
    {
        return m.Value;
    }

    public static implicit operator float(Measure m)
    {
        return (float) m.Value;
    }
    #endregion

    #region Properties
    public double Value { get; set; }
    #endregion

    #region Equality
    public static bool Equals(Measure a, Measure b)
    {
        // Constants.IsEqual checks abs(a - b) < Tolerance.
        return Constants.IsEqual(a.Value, b.Value);
    }
    public static bool Equals(Measure a, object b)
    {
        return a.Equals(b);
    }
    public static bool Equals(object a, Measure b)
    {
        return b.Equals(a);
    }
    public bool Equals(Measure other)
    {
        return Equals(this, other);
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
            return false;
        try
        {
            double d = Convert.ToDouble(obj);
            return Equals(d);
        }
        catch (InvalidCastException)
        {
            return false;
        }
        catch (Exception e)
        {
            // Shouldn't get here!
            Debug.Print("Unexpected exception in Measure.Equals: ", e);
            if (System.Diagnostics.Debugger.IsAttached)
                System.Diagnostics.Debugger.Break();
            return false;
        }
    }

    public static bool operator == (Measure x, Measure y)
    {
        return x.Equals(y);
    }
    public static bool operator != (Measure x, Measure y)
    {
        return !(x == y);
    }

    public override int GetHashCode()
    {
        return Value.GetHashCode();
    }
    #endregion
}

Я создал несколько методов расширения:

public static class ExtensionMethods
{
    public static bool Equals(this object a, Measure b)
    {
        return b.Equals(a);
    }
    public static bool Equals(this double a, Measure b)
    {
        return b.Equals(a);
    }
}

Я установил контрольные точки для каждой функции Equals, и они получают удар во время прохождения тестов, но ни одна из этих функций не вызывается для double.

Возможно ли это? Если да, что мне не хватает и как мне это реализовать?

Заранее спасибо за любые указатели.

Ian

...