Вы бы выставили его как IEnumerable<T>
, а не просто возвращали его напрямую:
public IEnumerable<object> Objects { get { return obs.Select(o => o); } }
Поскольку вы указали, что вам нужен только обход списка, это все, что вам нужно.
Может возникнуть соблазн вернуть List<object>
непосредственно как IEnumerable<T>
, но это было бы неправильно, поскольку можно легко проверить IEnumerable<T>
во время выполнения, определить, что это List<T>
, и привести его к и мутировать содержимое.
Однако, используя return obs.Select(o => o);
, вы в конечном итоге возвращаете итератор для List<object>
, а не прямую ссылку на сам List<object>
.
Некоторые могут подумать, что это квалифицируется как «вырожденное выражение» в соответствии с разделом 7.15.2.5 Спецификации языка C #. Тем не менее, Эрик Липперт подробно описывает, почему эта проекция не оптимизирована .
Кроме того, люди предлагают использовать метод расширения AsEnumerable . Это неверно, так как ссылочная идентичность исходного списка сохраняется. Из раздела «Замечания» документации:
Метод AsEnumerable<TSource>(IEnumerable<TSource>)
не имеет никакого другого эффекта, кроме как изменить тип источника времени компиляции с типа, который реализует IEnumerable<T>
на IEnumerable<T>
.
Другими словами, все, что он делает, это приводит параметр источника к IEnumerable<T>
, что не помогает защитить ссылочную целостность, возвращается исходная ссылка и может быть возвращена к List<T>
и использоваться для изменения списка .