web-dev-qa-db-fra.com

Comment implémenter une interface IComparable?

Je remplis un tableau avec des instances d'une classe:

BankAccount[] a;
. . .

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

Une fois que je remplis ce tableau, j'aimerais le trier par solde. Pour ce faire, j'aimerais pouvoir vérifier si chaque élément est triable à l'aide de IComparable.
Je dois le faire en utilisant des interfaces. Jusqu'à présent, j'ai le code suivant:

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

Mais je ne suis pas sûr que ce soit la bonne solution. Aucun conseil?

Vous ne devriez pas définir vous-même IComparable. C'est déjà défini.

Au lieu de cela, vous devez implémenter IComparable sur votre classe BankAccount.

Où vous avez défini le class BankAccount, assurez-vous qu’il implémente l’interface IComparable

Puis écrire BankAccout.CompareTo pour comparer les montants des soldes des deux objets.


Éditer

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 pour montrer la bonne réponse de Jeffrey L Whitledge:

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

    public int CompareTo(BankAccount that)
    {
        return this.Balance.CompareTo(that.Balance);
    }
}
123
abelenky

Voulez-vous de manière destructive trier le tableau? C'est-à-dire, voulez-vous réellement changer l'ordre des éléments dans le tableau? Ou voulez-vous simplement une liste des articles dans un ordre particulier, sans détruire l'ordre original?

Je suggérerais qu'il est presque toujours préférable de faire ce dernier. Pensez à utiliser LINQ pour un ordre non destructif. (Et envisagez d'utiliser un nom de variable plus significatif que "a".)

BankAccount[] bankAccounts = { whatever };
var sortedByBalance = from bankAccount in bankAccounts 
                      orderby bankAccount.Balance 
                      select bankAccount;
Display(sortedByBalance);
15
Eric Lippert

IComparable existe déjà dans .NET avec cette définition de CompareTo

int CompareTo(Object obj)

Vous n'êtes pas censé créer l'interface, vous êtes censé l'implémenter.

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.
    }
}
14
Lou Franco

Une alternative consiste à utiliser LINQ et à ignorer la mise en œuvre de IComparable:

BankAccount[] sorted = a.OrderBy(ba => ba.Balance).ToArray();
10
Matt Greer

Il existe déjà IComparable<T> , mais vous devriez idéalement prendre en charge à la fois IComparable<T> Et IComparable. Utiliser le Comparer<T>.Default Incorporé est généralement une option plus facile. Array.Sort, Par exemple, acceptera un tel comparateur.

5
Marc Gravell

Si vous avez seulement besoin de trier ces BankAccounts, utilisez LINQ comme suit

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

a = a.OrderBy(bank => bank.Balance).ToArray();
2
Zain Shaikh