Quelle est la meilleure façon de créer un tableau en lecture seule dans C #?

J’ai la situation extrêmement improbable et originale de vouloir retourner un tableau en lecture seule depuis ma propriété. Jusqu’à présent, je ne suis au courant que d’une seule façon – via System.Collections.ObjectModel.ReadOnlyCollection . Mais cela me semble quelque peu gênant, sans compter que cette classe perd la possibilité d’accéder aux éléments du tableau par leur index ( ajouté: whoops, j’ai manqué l’indexeur ). N’y a-t-il pas de meilleur moyen? Quelque chose qui pourrait rendre le tableau lui-même immuable?

Utilisez ReadOnlyCollection . Il est en lecture seule et, contrairement à ce que vous croyez, il comporte un indexeur.

Les tableaux ne sont pas immuables et il n’y a aucun moyen de les créer sans utiliser un wrapper comme ReadOnlyCollection .

Notez que la création d’un wrapper ReadOnlyCollection est une opération O (1) et n’entraîne aucun coût de performance.

Mettre à jour
D’autres réponses ont suggéré de simplement IReadOnlyList collections dans la nouvelle IReadOnlyList , qui étend IReadOnlyCollection pour append un indexeur. Malheureusement, cela ne vous donne pas vraiment le contrôle de la mutabilité de la collection car elle pourrait être renvoyée au type de collection d’origine et mutée.

Au lieu de cela, vous devez toujours utiliser la méthode ReadOnlyCollection (la méthode List AsReadOnly() ou la méthode statique d’ Array AsReadOnly() aide à envelopper les listes et les tableaux en conséquence) pour créer un access immuable , soit directement, soit comme l’une des interfaces IReadOnlyList charge, y compris IReadOnlyList .

.NET Framework 4.5 introduit IReadOnlyList qui s’étend depuis IReadOnlyCollection ajoutant T this[int index] { /*..*/ get; } T this[int index] { /*..*/ get; } .

Vous pouvez IReadOnlyList de T[] à IReadOnlyList . Un avantage de ceci est que le (IReadOnlyList)array est, à (IReadOnlyList)array égal à array ; aucune boxe n’est impliquée.

Bien sûr, comme un wrapper n’est pas utilisé, (T[])GetReadOnlyList() serait mutable.

À partir de .NET Framework 2.0, Array.AsReadOnly crée automatiquement un wrapper ReadOnlyCollection pour vous.

Si vous voulez vraiment qu’un tableau soit renvoyé, mais que le consommateur du tableau craigne les données internes, retournez simplement une copie du tableau. Personnellement, je pense toujours que ReadOnlyCollection est la voie à suivre, mais si vous voulez vraiment un tableau …..

Je pense à IEnumerable.

Vous voudrez peut-être implémenter l’interface IEnumerable et surcharger l’opérateur this [int] pour refuser l’access à son setter

Il existe désormais un support pour les collections immuables. Voir https://www.nuget.org/packages/System.Collections.Immutable

Cela prend en charge l’un des éléments suivants:

  • .NET 4.5 (ou supérieur)
  • .NETStandard 1.0 (ou supérieur)
  • Windows 8.0
  • WindowsPhone 8.0
  • WindowsPhoneApp 8.1
  • Bibliothèque de classes portable (.NETFramework 4.5, Windows 8.0, WindowsPhone 8.0, WindowsPhoneApp 8.1)