Mam pytanie dotyczące „najlepszych praktyk” na temat OOP w C # (ale w pewnym sensie dotyczy to wszystkich języków).
Zastanów się nad klasą biblioteki z obiektem, który ma być udostępniony publicznie, powiedzmy za pośrednictwem modułu dostępu do właściwości, ale nie chcemy, aby publiczność (ludzie używający tej klasy biblioteki) to zmieniła.
class A
{
// Note: List is just example, I am interested in objects in general.
private List<string> _items = new List<string>() { "hello" }
public List<string> Items
{
get
{
// Option A (not read-only), can be modified from outside:
return _items;
// Option B (sort-of read-only):
return new List<string>( _items );
// Option C, must change return type to ReadOnlyCollection<string>
return new ReadOnlyCollection<string>( _items );
}
}
}
Oczywiście najlepszym podejściem jest „opcja C”, ale bardzo niewiele obiektów ma wariant ReadOnly (a na pewno nie ma w nim klas zdefiniowanych przez użytkownika).
Gdybyś był użytkownikiem klasy A, czy spodziewałbyś się zmian
List<string> someList = ( new A() ).Items;
propagować do oryginalnego obiektu (A)? Czy może w porządku jest zwrócić klon pod warunkiem, że został napisany w komentarzach / dokumentacji? Myślę, że takie podejście do klonowania może prowadzić do dość trudnych do wyśledzenia błędów.
Pamiętam, że w C ++ mogliśmy zwracać obiekty const i można było wywoływać tylko metody oznaczone jako const. Myślę, że nie ma takiej funkcji / wzoru w C #? Jeśli nie, dlaczego mieliby tego nie uwzględniać? Uważam, że nazywa się to stałą poprawnością.
Ale znowu moje główne pytanie dotyczy „czego byś się spodziewał” lub jak poradzić sobie z opcją A w porównaniu z B.