C# - using List<T>.Find() with custom objects
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);
Comments
-
Pacane almost 2 years
I'm trying to use a
List<T>
with a custom class of mine, and being able to use methods likeContains()
,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 theFind()
...Note: Right now, I've overloaded the
Equals()
method to get theContains()
method to work, but I still couldn't get theFind()
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 over 13 yearswhat's this technique called ?
-
Greg Sansom over 13 years@Pacane: From msdn - All lambda expressions use the lambda operator =>, which is read as "goes to"
-
Greg Sansom over 13 yearsThese 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 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 over 9 yearsCan you provide a .NET 2.0 example? I'm in Unity3D which is stuck in .net 2.0 land
-
Hugo Allexis Cardona about 7 yearsIs 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 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 over 6 yearsAnd how to deal if the element is not found?
-
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.