web-dev-qa-db-fra.com

C # - utilisation de la liste <T> .Find () avec des objets personnalisés

J'essaie d'utiliser un List<T> avec une classe personnalisée et d'utiliser des méthodes telles que Contains(), Find(), etc., dans la liste. Je pensais que je devrais simplement surcharger l'opérateur == mais, apparemment, une solution consiste à utiliser une méthode déléguée avec la fonction Find()...

Remarque: pour l'instant, j'ai surchargé la méthode Equals() pour que la méthode Contains() fonctionne, mais je ne pouvais toujours pas faire fonctionner la fonction Find().

Quel serait le meilleur moyen de faire fonctionner les deux?

J'utilise la dernière version du framework C #/.NET avec mono, sur linux.

edit: Voici mon code

using System;
namespace GuerreDesClans
{
public class Reponse : IEquatable<Reponse>
{
    public Reponse ()
    {
        m_statement = string.Empty;
        m_pointage = 0;
    }

    public Reponse (string statement, int pointage)
    {
        m_pointage = pointage;
        m_statement = statement;
    }


    /*
     * attributs privés
     */

    private string m_statement;
    private int m_pointage;


    /*
     * properties
     */

    public string Statement {
        get { return m_statement; }
        set { m_statement = value; }
    }

    public int Pointage {
        get { return m_pointage; }
        set { m_pointage = value; }
    }

    /*
     * Equatable
     */

    public bool Equals (Reponse other)
    {
        if (this.m_statement == other.m_statement)
            return true;
        else
            return false;
    }
}

}

et comment j'aimerais rechercher mes objets Reponse en utilisant la fonction find () ...

list.find("statement1"); // would return a Reponse object
38
Pacane

Find () trouvera l'élément qui correspond au prédicat que vous transmettez en tant que paramètre. Par conséquent, il n'est pas lié à Equals () ou à l'opérateur ==.

var element = myList.Find(e => [some condition on e]);

Dans ce cas, j'ai utilisé une expression lambda comme prédicat. Vous voudrez peut-être lire à ce sujet. Dans le cas de Find (), votre expression doit prendre un élément et renvoyer un bool.

Dans votre cas, ce serait:

var reponse = list.Find(r => r.Statement == "statement1")

Et pour répondre à la question dans les commentaires, c'est l'équivalent dans .NET 2.0, avant l'introduction des expressions lambda:

var response = list.Find(delegate (Response r) {
    return r.Statement == "statement1";
});
58
Xavier Poinas

Vous pouvez utiliser find avec un prédicat comme suit:

list.Find(x => x.Id == IdToFind);

Cela retournera le premier objet de la liste qui remplit les conditions définies par le prédicat (c'est-à-dire que dans mon exemple, je cherche un objet avec un ID).

44
Greg Sansom

Les réponses précédentes ne tiennent pas compte du fait que vous avez surchargé l'opérateur égal et que vous l'utilisez pour tester l'élément recherché. Dans ce cas, votre code ressemblerait à ceci:

list.Find(x => x == objectToFind);

Ou, si vous n'aimez pas la syntaxe lambda et que vous avez substitué object.Equals (objet) ou avez implémenté IEquatable <T>, vous pouvez procéder comme suit:

list.Find(objectToFind.Equals);
6
phoog

http://msdn.Microsoft.com/en-us/library/x0b5b5bc.aspx

        // Find a book by its ID.
        Book result = Books.Find(
        delegate(Book bk)
        {
            return bk.ID == IDtoFind;
        }
        );
        if (result != null)
        {
            DisplayResult(result, "Find by ID: " + IDtoFind);   
        }
        else
        {
            Console.WriteLine("\nNot found: {0}", IDtoFind);
        }
1
Shimon Doodkin