В моей программе есть структура, представляющая меру, которую я хочу взаимозаменять с двойной.
Я реализовал это, и все, кажется, работает нормально, за исключением одного из моих тестов:
[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