如何实现IComparable接口?

l--*_*''' 70 c# interface icomparable

我正在使用类的实例填充数组:

BankAccount[] a;
. . .

a = new BankAccount[]
{
    new BankAccount("George Smith", 500m),
    new BankAccount("Sid Zimmerman", 300m)
};
Run Code Online (Sandbox Code Playgroud)

一旦我填充这个数组,我想按余额金额对它进行排序.为了做到这一点,我希望能够检查每个元素是否可以使用排序IComparable.
我需要使用接口来做到这一点.到目前为止,我有以下代码:

public interface IComparable
{
    decimal CompareTo(BankAccount obj);
}
Run Code Online (Sandbox Code Playgroud)

但我不确定这是否是正确的解决方案.有什么建议?

abe*_*nky 126

你不应该自己定义IComparable.它已经定义了.

相反,您需要在您的类上实现 IComparable IComparable.

您定义的位置IComparable,请确保它实现IComparable接口

然后写入BankAccount比较两个对象的余额.


编辑

public class BankAccount : IComparable<BankAccount>
{
    [...]

    public int CompareTo(BankAccount that)
    {
        if (this.Balance >  that.Balance) return -1;
        if (this.Balance == that.Balance) return 0;
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑2以显示Jeffrey L Whitledge的好答案:

public class BankAccount : IComparable<BankAccount>
{
    [...]

    public int CompareTo(BankAccount that)
    {
        return this.Balance.CompareTo(that.Balance);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢`return this.Balance.CompareTo(that.Balance);` (39认同)
  • 在第一个版本中,应该是`this.Balance <that.Balance`按平衡升序排序.-1 =这小于,0 =这等于,1 =这大于那个 (5认同)
  • 另一种方式是`return Balance - that.Balance;` (4认同)
  • `return Balance - that.Balance`如果天平接近其类型的极限不是一个好主意,因为溢出可能会给你错误的结果.例如,如果Balance是一个`short`,`this.Balance`是32700而`that.Balance`是-100,减法的结果将是-32736,当`CompareTo`的结果显然应该是正数.同样,如果Balance是一个'ushort`,减法的结果永远不会是负数,这也显然是错误的. (4认同)
  • 我是一个女孩 - 我不确定你的意思.也许您不清楚我要替换的代码部分.我将把所有这些都放在注释中,然后:`public class BankAccount:IComparable <BankAccount> {[...] int CompareTo(BankAccount that){return this.Balance.CompareTo(that.Balance); 那更清楚了吗? (3认同)

Lou*_*nco 15

IComparable 已经存在于.NET中,具有CompareTo的这个定义

int CompareTo(Object obj)
Run Code Online (Sandbox Code Playgroud)

你不应该创建接口 - 你应该实现它.

public class BankAccount : IComparable {

    int CompareTo(Object obj) {
           // return Less than zero if this object 
           // is less than the object specified by the CompareTo method.

           // return Zero if this object is equal to the object 
           // specified by the CompareTo method.

           // return Greater than zero if this object is greater than 
           // the object specified by the CompareTo method.
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果obj是`null`或者是另一种类型而不是`BankAccount`怎么办?编辑:根据MSDN在这里:https://msdn.microsoft.com/en-us/library/system.icomparable.compareto(v=vs.110).aspx#Anchor_1:抛出一个`ArgumentException`. (2认同)

Eri*_*ert 15

你想破坏性地排序数组吗?也就是说,您是否想要实际更改数组中项目的顺序?或者您只想要特定顺序的项目列表,而不破坏原始订单?

我建议做后者几乎总是更好.考虑使用LINQ进行非破坏性排序.(并考虑使用比"a"更有意义的变量名称.)

BankAccount[] bankAccounts = { whatever };
var sortedByBalance = from bankAccount in bankAccounts 
                      orderby bankAccount.Balance 
                      select bankAccount;
Display(sortedByBalance);
Run Code Online (Sandbox Code Playgroud)

  • @Lippert:虽然这是一个非常有效的响应,但从讨论中可以看出,OP几乎不了解实现接口的含义.她可能还没有为你提出的问题做好准备. (7认同)

Mat*_*eer 10

另一种方法是使用LINQ并完全跳过实现IComparable:

BankAccount[] sorted = a.OrderBy(ba => ba.Balance).ToArray();
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 5

已经存在IComparable<T>,但理想情况下你应该同时支持IComparable<T>IComparable.使用内置Comparer<T>.Default通常是一个更容易的选择.Array.Sort例如,将接受这样的比较器.