Is IEnumerable more waterproof than IReadOnlyList?

I read this question: IEnumerable vs IReadonlyCollection vs ReadonlyCollection to publish a list item and this question: ReadOnlyCollection or IEnumerable to expose member collections? . I understand that these answers were written many years ago.

Jon Skeet's answer suggests that I should use IReadOnlyCollection and not IEnumerable, as I am very careful to prevent such code:

ICollection<Order> evil = (ICollection<Order>)customer.Orders;
evil.Add(order3);

Now look at 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 as follows:

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);

? , . , IReadOnlyCollection? ? , , .

:

  • IEnumerable .

  • .

: https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/guidelines-for-collections.

+4
2

, :

public IReadOnlyList<Order> Orders => _orders.AsReadOnly();

List , "" :

ICollection<Order> evil = (ICollection<Order>)customer.Orders;
evil.Add(order3);

, collectciton . IEnumerable , , (- ).

, , . IEnumerable - IReadOnlyList .

- , IEnumerable - Count() LINQ, yield return , . IReadOnlyList Count, .

, , VS api. , api :

IEnumerable<Order> orders = customer2.Orders;
// just an example, there is actually no need to check for count
// before enumerating
if (orders.Count() > 0) {
    foreach (var order in orders) {

    }
}

foreach VS " IEnumerable". , caller IEnumerable, , . . , , - var orders = customer.Orders.ToList(), .

api , api.

+1

, IReadOnlyCollection?

. , -.

? ?

? , . yield return , . , .

: count O(n) O(1). .

+2

Source: https://habr.com/ru/post/1696219/


All Articles