I have read this question: IEnumerable vs IReadonlyCollection vs ReadonlyCollection for exposing a list member and this question: ReadOnlyCollection or IEnumerable for exposing member collections?. I am concious that these answers were written years ago.
The answer by Jon Skeet suggests that I should be using a IReadOnlyCollection rather than an IEnumerable as I am very cautious to prevent code like this:
ICollection<Order> evil = (ICollection<Order>)customer.Orders;
evil.Add(order3);
Now see the code below:
public class Customer
{
private readonly List<Order> _orders = new List<Order>();
public string FirstName { get; set; }
public string LastName { get; set; }
public IEnumerable<Order> Orders
{
get { foreach (var order in _orders) yield return order; }
}
internal void AddOrder(Order order)
{
_orders.Add(order);
}
public void AddOrders(IEnumerable<Order> orders)
{
this._orders.AddRange(orders);
}
}
I can use the code like this:
Order order1 = new Order();
Order order2 = new Order();
Order order3 = new Order();
Customer customer = new Customer();
customer.FirstName = "Fred";
customer.LastName = "Bloggs";
customer.AddOrder(order1);
customer.AddOrder(order2);
and like this:
Customer customer2 = new Customer();
customer2.FirstName = "Average";
customer2.LastName = "Joe";
List<Order> orders = new List<Order>();
Order order4 = new Order();
Order order5 = new Order();
orders.Add(order4);
orders.Add(order5);
customer2.AddOrders(orders);
Are there any risks using this code? I am trying to make it as water tight as possible as it is part of a public api. Is this more water tight than an IReadOnlyCollection? Is it less efficient? Please note that this is the final version of the code so there are no other scenarios to consider.
The concerns I have are:
Exposing an IEnumerable instead of a readonly list.
Using a List to hold the orders privately.
I am trying to follow the advice described here as best I can: https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/guidelines-for-collections.