I have the following classes:
public class MyDocuments
{
public DateTime registeredDate;
public string version;
public List<Document> registeredDocuments;
}
public class Document
{
public string name;
public List<File> registeredFiles;
}
public class File
{
public string name;
public string content;
}
I have an instance of MyDocuments which has several documents in List<Document> registeredDocument. I get a new List<Document> from the user.
How can I verify that the new object doesn’t exist in the list? I want to compare by value not reference.
I’m thinking of using HashSet instead of List. Is this the proper approach?
How are equality comparisons performed?
Whenever the BCL classes want to perform an equality check between objects of some type
T, they do so by calling one or both of the methods in some implementation ofIEqualityComparer<T>. To get hold of such an implementation, the framework looks toEqualityComparer<T>.Default.As mentioned in the documentation, this property produces an
IEqualityComparer<T>like this:What are my options?
So, in general, to dictate how equality comparisons should be performed you can:
IEqualityComparer<T>to the class or method that performs equality checks. This option is not very visible withList<T>, but many LINQ methods (such asContains) do support it.IEquatable<T>. This will makeEqualityComparer<T>.Defaultuse this implementation, and is a good choice whenever there is an obvious “natural” way to compare objects of typeT.object.GetHashCodeandobject.Equalswithout implementingIEqualityComparer<T>. However, this is simply an inferior version of #2 and AFAIK should always be avoided.Which option to pick?
A good rule of thumb is: if there is an obvious and natural way to compare objects of class
T, consider having it implementIEquatable<T>; this will make sure your comparison logic is used throughout the framework without any additional involvement. If there is no obvious candidate, or if you want to compare in a manner different than the default, implement your ownIEqualityComparer<T>and pass the implementation as an argument to the class or method that needs to perform equality checks.