Jak zwykle tylko powrócić niezmienne (żadnych modyfikacji) obiektów z właściwości/metod, odpowiedź ta zakłada, że chcesz zrobić to samo.
Nie zapomnij o ReadOnlyCollection<T>
który zwraca niezmienny kolekcji, które można jeszcze otworzyć przez indeks.
Jeśli używasz IEnumerable<T>
i uwalniając swój typ na pustynię niekontrolowany, uważać na to:
:
class MyClass {
private List<int> _list;
public IEnumerable<int> Numbers {
get { return _list; }
}
}
Jako użytkownik może to i bałagan wewnętrzny stan swojej klasie zrobić
var list = (List<int>)myClass.Numbers;
list.Add(123);
To narusza intencję tylko do odczytu dla nieruchomości. W takich przypadkach, twoja rodzicielka powinna wyglądać następująco:
public IEnumerable<int> Numbers {
get { return new ReadOnlyCollection<int>(_list); }
}
Alternatywnie można nazwać _list.ToReadOnly()
. Napisałem go w całości, aby pokazać typ.
To powstrzyma każdego, kto zmieni twój stan (chyba że użyje refleksji, ale to naprawdę trudno zatrzymać, chyba że zbudujesz niezmienne kolekcje, takie jak te używane w wielu funkcjonalnych językach programowania, i to zupełnie inna historia).
Jeśli zwracasz kolekcję tylko do odczytu, lepiej będzie, gdy określisz członka jako ReadOnlyCollection<T>
, ponieważ wtedy niektóre akcje będą działały szybciej (liczenie, dostęp do elementów według indeksu, kopiowanie do innej kolekcji).
Osobiście chciałbym zobaczyć ramy obejmują i wykorzystywać interfejs tak:
public interface IReadOnlyCollection<T> : IEnumerable<T>
{
T this[int index] { get; }
int Count { get; }
bool Contains(T item);
void CopyTo(T[] array, int arrayIndex);
int IndexOf(T item);
}
można uzyskać wszystkie te funkcje za pomocą metody rozszerzenie na górze IEnumerable<T>
ale nie są one tak wydajnych.
Należy zauważyć, że wszystkie powyższe typy obsługują Linq w różnym stopniu, poprzez 'IEnumerable' lub 'IQueryable '. –