I have a class, which looks like this:
public class Customer
{
private readonly IList<Order> _orders = new List<Order>();
public FirstName FirstName { get; set; }
public LastName LastName { get; set; }
public Province Province { get; set; }
public IEnumerable<Order> Orders
{
get { foreach (var order in _orders) yield return order; }
}
internal void AddOrder(Order order)
{
_orders.Add(order);
}
//Planning to add an AddRange method to add a collection of Orders.
}
Someone suggested to me recently that I should be using a Set instead of a list as I do not need the index benefits of a list as it is exposed as an IEnumberable.
If I change this to a set, then how do I implement equality? I believe I have a few options:
1) Leave it as a list.
2) Do nothing - then I believe orders are unique based on referential equality. Is there any risk doing this? Everywhere I read tells me that you must override Hashcode and equals if you are using a Hashset. Here is an example of a Set, where the default Object.hashcode and object.equals appears to be used with a HashSet: https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate.DomainModel/Northwind/Entities/Order.cs
3) Override .equals and .hashcode in the Order class so that Orders are equal if they have the same ID. This link suggests that you should not do this: https://www.youtube.com/watch?v=xRCOKKUSp9s
4) Create an Entity base class similar to this: https://github.com/VaughnVernon/IDDD_Samples_NET/blob/master/iddd_common/Domain.Model/Entity.cs. The youtube video in point three appears to advise against this.
5) Implement an IEqualityComparer. The research I have done suggests this is a bad idea because: 1) I will have to inject/pass a comparer into the entity and 2) The code for establising whether two orders are equal is in a different class to Order making the domain model anemic.
I am trying to follow the principle of least astonishment and find myself going round in circles sometimes trying to achieve this. A lot of the links above are several years old. Is there a standard way to approach this?
Someone suggested to me recently that I should be using a Set instead of a list as I do not need the index benefits
and? Did that someone also say why is that so terrible? KISS!!! If using Set is causing you too much overhead, go with Lists. Do refactor later if you deem it necessary – Laiv Apr 14 '18 at 11:09