Множество способов.
Самого наивный подход был бы всегда скопировать частное поле:
return _strings.ToList();
Но это вообще не нужно. Это бы имеет смысл, хотя, если:
- Вы случайно не знаете, что вызывающий код, как правило, хотят
List<T>
в любом случае, так что вы могли бы также дать один назад (не подвергая оригинал).
- Для выставленного объекта важно сохранить исходные значения, даже если исходная коллекция впоследствии будет изменена.
В качестве альтернативы, вы можете просто выставить только для чтения обертку:
return _strings.AsReadOnly();
Это более эффективно, чем первый вариант, но подвергнет изменения, внесенные в основной коллекции.
Эти стратегии также могут быть объединены. Если вам нужна копия оригинальной коллекции (поэтому изменения в оригинал не имеют никакого эффекта), но и не хотят, чтобы объект вернулся, чтобы быть изменяемым *, вы могли бы пойти с:
// copy AND wrap
return _strings.ToList().AsReadOnly();
Вы можете также использовать yield
:
foreach (string s in _strings)
{
yield return s;
}
Это похоже на эффективность и компромиссы по первому варианту, но с отсроченным исполнением.
Очевидно, что ключевое значение, которое следует учесть здесь, заключается в том, как ваш метод действительно будет использоваться и какую функциональность, именно, вы хотите обеспечить этим свойством.
* Хотя, честно говоря, я не уверен, почему вам все равно.
Использование 'IEnumerable' разумно здесь, если ваша (замечательная) цель - ограничить операции, которые могут выполнять пользователи. Если бы вы решили вернуть, скажем, массив вместо этого, вам не повезло; вы должны делать копию каждый раз. –
@mattytommo: Нет доступа к аксессуарам. Для изменения коллекции вам не нужен набор средств доступа; вот в чем вопрос. –
@mattytommo: Проблема не в том, что * Строки * будут меняться. Проблема в том, что * объект, возвращаемый Strings, сам является mutable *. –