В зоопарке
IEnumerable, IReadOnlyCollection, IList легко потеряться. Разберёмся, зачем существует IReadOnlyList и другие, а также в чём их сила.Логика выбора интерфейсов
1.
IEnumerable — объект можно «пройти в foreach». Отлично подходит для ленивых источников данных: стриминг строк из файла, результаты SQL-запроса.2.
IReadOnlyCollection — то же самое, что IEnumerable, но добавляет индексатор.3.
IReadOnlyList — это уже полноценный «read-only список»: доступ по индексу и Count гарантированы. Интерфейс хорош, если ваш метод или сервис работает именно со списком.4.
IList — даёт полный доступ и чтение, и запись. Подходит для внутренней логики, но в публичных контрактах часто избыточен.// ✅ Когда реально нужен индекс и Count — просим IReadOnlyList<T>
int SumAtOddIndices(IReadOnlyList<int> items)
{
var sum = 0;
for (int i = 1; i < items.Count; i += 2)
sum += items[i];
return sum;
}
// ✅ Публичный контракт, где важно "списочно и read-only"
public interface IOrderService
{
IReadOnlyList<Order> GetRecent();
// клиент может перебирать и индексировать,
// но не может добавить/удалить заказы
}
// ✅ Стриминг из источника — только перечислить
public static IEnumerable<string> ReadLines(Stream s)
{
using var r = new StreamReader(s);
while (!r.EndOfStream)
yield return r.ReadLine()!;
}
Такой подход делает контракты честными и код предсказуемым, а лишние
.ToList() уходят в прошлое.🐸Библиотека шарписта
#буст
