How to Implement IComparable interface?

2019-01-04 10:18发布

I am populating an array with instances of a class:

BankAccount[] a;
. . .

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

Once I populate this array, I would like to sort it by balance amounts. In order to do that, I would like to be able to check whether each element is sortable using IComparable.
I need to do this using interfaces. So far I have the following code:

public interface IComparable
{
    decimal CompareTo(BankAccount obj);
}

But I'm not sure if this is the right solution. Any advice?

6条回答
仙女界的扛把子
2楼-- · 2019-01-04 10:26

An alternative is to use LINQ and skip implementing IComparable altogether:

BankAccount[] sorted = a.OrderBy(ba => ba.Balance).ToArray();
查看更多
叛逆
3楼-- · 2019-01-04 10:28

IComparable already exists in .NET with this definition of CompareTo

int CompareTo(Object obj)

You are not supposed to create the interface -- you are supposed to implement it.

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.
    }
}
查看更多
叼着烟拽天下
4楼-- · 2019-01-04 10:30

If you only need to sort these BankAccounts, use LINQ like following

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

a = a.OrderBy(bank => bank.Balance).ToArray();
查看更多
SAY GOODBYE
5楼-- · 2019-01-04 10:34

You should not define IComparable yourself. It is already defined.

Rather, you need to implement IComparable on your BankAccount class.

Where you defined the class BankAccount, make sure it implements the IComparable interface

Then write BankAccout.CompareTo to compare the balance amounts of the two objects.


Edit

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;
    }
}

Edit 2 to show Jeffrey L Whitledge's good answer:

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

    public int CompareTo(BankAccount that)
    {
        return this.Balance.CompareTo(that.Balance);
    }
}
查看更多
何必那么认真
6楼-- · 2019-01-04 10:35

There is already IComparable<T>, but you should ideally support both IComparable<T> and IComparable. Using the inbuilt Comparer<T>.Default is generally an easier option. Array.Sort, for example, will accept such a comparer.

查看更多
来,给爷笑一个
7楼-- · 2019-01-04 10:43

Do you want to destructively sort the array? That is, do you want to actually change the order of the items in the array? Or do you just want a list of the items in a particular order, without destroying the original order?

I would suggest that it is almost always better to do the latter. Consider using LINQ for a non-destructive ordering. (And consider using a more meaningful variable name than "a".)

BankAccount[] bankAccounts = { whatever };
var sortedByBalance = from bankAccount in bankAccounts 
                      orderby bankAccount.Balance 
                      select bankAccount;
Display(sortedByBalance);
查看更多
登录 后发表回答