C# - using List<T>.Find() with custom objects

185,416

Solution 1

Find() will find the element that matches the predicate that you pass as a parameter, so it is not related to Equals() or the == operator.

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

In this case, I have used a lambda expression as a predicate. You might want to read on this. In the case of Find(), your expression should take an element and return a bool.

In your case, that would be:

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

And to answer the question in the comments, this is the equivalent in .NET 2.0, before lambda expressions were introduced:

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

Solution 2

You can use find with a Predicate as follows:

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

This will return the first object in the list which meets the conditions defined by the predicate (ie in my example I am looking for an object with an ID).

Solution 3

Previous answers don't account for the fact that you've overloaded the equals operator and are using that to test for the sought element. In that case, your code would look like this:

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

Or, if you don't like lambda syntax, and have overriden object.Equals(object) or have implemented IEquatable<T>, you could do this:

list.Find(objectToFind.Equals);
Share:
185,416
Pacane
Author by

Pacane

wat?

Updated on July 09, 2022

Comments

  • Pacane
    Pacane almost 2 years

    I'm trying to use a List<T> with a custom class of mine, and being able to use methods like Contains(), Find(), etc., on the list. I thought I'd just have to overload the operator == but apparently, one way of doing that is to use a delegate method with the Find()...

    Note: Right now, I've overloaded the Equals() method to get the Contains() method to work, but I still couldn't get the Find() function to work.

    What would be the best way of getting both to work?

    I'm using the latest C# /.NET framework version with mono, on linux.

    edit: Here's my 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;
        }
    }
    

    }

    and how I would like to search my Reponse objects using the find() function...

    list.find("statement1"); // would return a Reponse object
    
  • Pacane
    Pacane over 13 years
    what's this technique called ?
  • Greg Sansom
    Greg Sansom over 13 years
    @Pacane: From msdn - All lambda expressions use the lambda operator =>, which is read as "goes to"
  • Greg Sansom
    Greg Sansom over 13 years
    These statements are both redundant because we already have a reference to objectToFind. The point of Find() is to locate an object we don't have a reference to. It's much easier, more logical and readable to use list.Contains(objectToFind).
  • phoog
    phoog over 13 years
    @Greg Sansom: Of course. But the OP specifically said that he has the Contains method working, but also wants to use Find. Since he has overridden Equals to compare m_statement and ignore the value of m_pointage, the Find method would not necessarily return the same instance that is passed to it. The behavior of the Equals override may be questionable, but given that behavior, list.Find(obj.Equals) is not redundant.
  • gman
    gman over 9 years
    Can you provide a .NET 2.0 example? I'm in Unity3D which is stuck in .net 2.0 land
  • Hugo Allexis Cardona
    Hugo Allexis Cardona about 7 years
    Is it ok to think that the returned element will be a reference and that any modifications to it will be reflected on that same element contained in the list?
  • Xavier Poinas
    Xavier Poinas about 7 years
    @HugoAllexisCardona If the type of the element is a reference type, then yes. If it is a value type, then no. See msdn.microsoft.com/en-us/library/t63sy5hs.aspx.
  • Olivier Pons
    Olivier Pons over 6 years
    And how to deal if the element is not found?
  • Xavier Poinas
    Xavier Poinas over 6 years
    @OlivierPons If the list contains reference types, Find will return null if the element is not found. If the list contains value types, it will return the default value for that type if the element is not found. In that case, there is no way to know if the element was found or not, unless the default value cannot match the predicate.