Я не могу принять выбранный ответ. Существуют способы справиться с описанным сценарием, но использование List или чего-либо еще, что вы используете, не является одним из них. В тот момент, когда IEnumerable возвращается, вы должны предположить, что вызывающая сторона может выполнить foreach. В этом случае не имеет значения, является ли конкретный тип списком или спагетти. На самом деле проблема заключается только в индексации, особенно если элементы удалены.
Любое возвращаемое значение является снимком. Это может быть текущее содержимое IEnumerable; в этом случае, если он кэшируется, он должен быть клоном кэшированной копии; если он должен быть более динамичным (например, результаты SQL-запроса), тогда используйте yield return; однако, позволяя контейнеру изменяться по желанию, и предоставляя методы, такие как Count и indexer, - это рецепт катастрофы в многопоточном мире. Я даже не узнал, что вызывающая сторона может вызывать кнопку «Добавить» или «Удалить» для контейнера, который должен контролировать ваш код.
Также возвращение конкретного типа блокирует вас в реализации. Сегодня внутри вы можете использовать список. Завтра, может быть, вы станете многопоточным и захотите использовать потокобезопасный контейнер, массив, очередь, коллекцию значений словаря или вывод запроса Linq. Если вы привязываетесь к конкретному типу возвращаемого значения, то перед возвратом вам придется либо изменить код, либо выполнить преобразование.