实现 IComparable 接口
Implementing the IComparable Interface
我正在阅读《c#6.0 in a Nutshell》这本书,下面的代码是关于主题 "Implementing the IComparable Interfaces"。
我不明白一些事情:
- 为什么
IComparable.CompareTo
在那里明确实施?
- 如果这只是
CompareTo
的另一个隐式重载(一个隐式
int CompareTo (Note other)
,另一个隐式 int CompareTo (object other)
?
public struct Note : IComparable<Note>, IEquatable<Note>, IComparable
{
int _semitonesFromA;
public int SemitonesFromA { get { return _semitonesFromA; } }
public Note (int semitonesFromA)
{
_semitonesFromA = semitonesFromA;
}
public int CompareTo (Note other) // Generic IComparable<T>
{
if (Equals (other)) return 0; // Fail-safe check
return _semitonesFromA.CompareTo (other._semitonesFromA);
}
int IComparable.CompareTo (object other) // Nongeneric IComparable
{
if (!(other is Note))
throw new InvalidOperationException ("CompareTo: Not a note");
return CompareTo ((Note) other);
}
public static bool operator < (Note n1, Note n2)
=> n1.CompareTo (n2) < 0;
public static bool operator > (Note n1, Note n2)
=> n1.CompareTo (n2) > 0;
public bool Equals (Note other) // for IEquatable<Note>
=> _semitonesFromA == other._semitonesFromA;
public override bool Equals (object other)
{
if (!(other is Note)) return false;
return Equals ((Note) other);
}
public override int GetHashCode() => _semitonesFromA.GetHashCode();
public static bool operator == (Note n1, Note n2) => n1.Equals (n2);
public static bool operator != (Note n1, Note n2) => !(n1 == n2);
}
你可以隐含地实现IComparable
,是的。但从根本上说,您想阻止用户将 Note
与另一个 Note
以外的任何内容进行比较。如果 IComparable
,您可能有遗留用法,但如果有人直接知道 Note
class,您不想允许:
Note note = new Note();
Other other = new Other();
int result = note.CompareTo(other);
你知道这总是会引发异常,那么为什么要允许它呢?基本上,将非通用 IComparable
接口视为 "somewhat legacy"(有有效用途,但是......)并通过显式实现来阻止任何人使用它。
我正在阅读《c#6.0 in a Nutshell》这本书,下面的代码是关于主题 "Implementing the IComparable Interfaces"。
我不明白一些事情:
- 为什么
IComparable.CompareTo
在那里明确实施? - 如果这只是
CompareTo
的另一个隐式重载(一个隐式int CompareTo (Note other)
,另一个隐式int CompareTo (object other)
?
public struct Note : IComparable<Note>, IEquatable<Note>, IComparable
{
int _semitonesFromA;
public int SemitonesFromA { get { return _semitonesFromA; } }
public Note (int semitonesFromA)
{
_semitonesFromA = semitonesFromA;
}
public int CompareTo (Note other) // Generic IComparable<T>
{
if (Equals (other)) return 0; // Fail-safe check
return _semitonesFromA.CompareTo (other._semitonesFromA);
}
int IComparable.CompareTo (object other) // Nongeneric IComparable
{
if (!(other is Note))
throw new InvalidOperationException ("CompareTo: Not a note");
return CompareTo ((Note) other);
}
public static bool operator < (Note n1, Note n2)
=> n1.CompareTo (n2) < 0;
public static bool operator > (Note n1, Note n2)
=> n1.CompareTo (n2) > 0;
public bool Equals (Note other) // for IEquatable<Note>
=> _semitonesFromA == other._semitonesFromA;
public override bool Equals (object other)
{
if (!(other is Note)) return false;
return Equals ((Note) other);
}
public override int GetHashCode() => _semitonesFromA.GetHashCode();
public static bool operator == (Note n1, Note n2) => n1.Equals (n2);
public static bool operator != (Note n1, Note n2) => !(n1 == n2);
}
你可以隐含地实现IComparable
,是的。但从根本上说,您想阻止用户将 Note
与另一个 Note
以外的任何内容进行比较。如果 IComparable
,您可能有遗留用法,但如果有人直接知道 Note
class,您不想允许:
Note note = new Note();
Other other = new Other();
int result = note.CompareTo(other);
你知道这总是会引发异常,那么为什么要允许它呢?基本上,将非通用 IComparable
接口视为 "somewhat legacy"(有有效用途,但是......)并通过显式实现来阻止任何人使用它。