Bene, per prima cosa .net ha introdotto IReadOnlyList e IReadOnlyDictionary che risolvono questo problema per i generici (che è preferibile ad un array di base), in precedenza avresti dovuto creare la tua interfaccia per vedere la stessa performance con stessa restrizione.
Il problema di base, e no, non è limitato agli array, è che si desidera fornire un metodo per accedere a un gruppo di elementi senza richiedere che vengano iterati, ma non si vuole che il consumatore della propria API sia aggiunta o eliminazione di elementi, ma in precedenza tutte le interfacce incorporate che consentono ciò che si desidera, consentivano anche ciò che non si desidera.
La soluzione suggerita è al contempo inefficiente (la creazione di un clone è lenta) e fuorviante - il consumatore ottiene una matrice che pensa che può modificare e avere quell'effetto l'oggetto che la ha restituita. Cioè pensa che se aggiunge un elemento e poi chiama di nuovo la proprietà, otterrà un array con p + 1 elementi. Si aspetta anche che o.ItemArray.Equals (o.ItemArray). Nessuna di queste aspettative sarà vera.
Come problema pratico, questo non è più un problema se puoi usare la versione corretta del framework e qualcosa di diverso da un array.
Per quanto riguarda il problema di prestazioni ...
if(o.ItemArray.Equals(o.ItemArray) || o.ItemArray.Equals(o2.ItemArray))
Crea 4 copie di un array potenzialmente grande.
Modifica in risposta al commento:
Questo non è un problema specifico degli array. Elenco e dizionari sono anche modificabili.
IList<string> lst = new List<string>();
lst.Add("hello");
lst[0]="bye";
Console.WriteLine(lst[0]);
E l'esempio di codice sopra mostra i problemi con l'elenco mutabile come proprietà. Supponiamo che io abbia avuto una lezione, Saluti, che contiene un elenco di parole e frasi che useresti quando incontri qualcuno. Ciao, Ciao, Hola, Ehi amico, Whats up! Como esta e così via. Quindi, ho una proprietà Words e restituisco il precedente lst. Puoi quindi eseguire immediatamente la terza riga e cambiare il mio "ciao" in "ciao" - per tutti quelli che hanno un riferimento a quell'istanza della classe.
Ma come ho detto, nel 4.5, avresti aggirato questo facendo sì che la tua lista fosse IReadOnlyLst e, usando questo ...
return (IReadOnlyList<string>) lst;