Je viens de tomber sur le ArraySegment<byte>
type en sous-classant la MessageEncoder
classe.
Je comprends maintenant que c'est un segment d'un tableau donné, prend un décalage, n'est pas énumérable et n'a pas d'indexeur, mais je ne comprends toujours pas son utilisation. Quelqu'un peut-il expliquer avec un exemple?
ArraySegment
énumérable dans .Net 4.5.Réponses:
ArraySegment<T>
est devenu beaucoup plus utile dans .NET 4.5 + et .NET Core car il implémente désormais:IList<T>
ICollection<T>
IEnumerable<T>
IEnumerable
IReadOnlyList<T>
IReadOnlyCollection<T>
contrairement à la version .NET 4 qui n'implémentait aucune interface.
La classe est maintenant capable de prendre part au monde merveilleux de LINQ afin que nous puissions faire les choses LINQ habituelles comme interroger le contenu, inverser le contenu sans affecter le tableau d'origine, obtenir le premier élément, et ainsi de suite:
la source
GetEnumerator
privés, ce qui signifie que vous êtes obligé de lancerIEnumerable<T>
(une conversion de boxe) pour l'appeler. Pouah!Dans cet exemple, nous examinons comment vous pouvez utiliser le tableau d'origine, les propriétés Offset et Count, ainsi que comment vous pouvez parcourir les éléments spécifiés dans ArraySegment.
ArraySegment Structure - à quoi pensaient-ils?
la source
i < segment.Offset + segment.Count
.C'est une petite structure de soldat chétive qui ne fait rien d'autre que garder une référence à un tableau et stocke une plage d'index. Un peu dangereux, sachez qu'il ne fait pas de copie des données du tableau et ne rend en aucun cas le tableau immuable ni n'exprime le besoin d'immuabilité. Le modèle de programmation le plus typique consiste simplement à conserver ou à transmettre le tableau et une variable ou un paramètre de longueur, comme cela se fait dans les méthodes .NET BeginRead (), String.SubString (), Encoding.GetString (), etc., etc.
Il n'est pas beaucoup utilisé dans le .NET Framework, sauf pour ce qui semble être un programmeur Microsoft particulier qui a travaillé sur les sockets Web et WCF l'aimant. Ce qui est probablement le bon guide, si vous l'aimez, utilisez-le. Il a fait un coup d'oeil dans .NET 4.6, la méthode supplémentaire MemoryStream.TryGetBuffer () l'utilise.
out
Je préfère avoir deux arguments que je suppose.En général, la notion plus universelle de tranches figure en bonne place sur la liste de souhaits des principaux ingénieurs .NET comme Mads Torgersen et Stephen Toub. Ce dernier a lancé la
array[:]
proposition de syntaxe il y a quelque temps, vous pouvez voir ce à quoi ils ont pensé dans cette page Roslyn . Je suppose que cela dépend en fin de compte d'obtenir le support CLR. Ceci est activement réfléchi pour la version 7 de C # afaik, gardez un œil sur System.Slices .Mise à jour: lien mort, livré dans la version 7.2 en tant que Span .
Update2: plus de support dans C # version 8.0 avec les types Range et Index et une méthode Slice ().
la source
Qu'en est-il d'une classe wrapper? Juste pour éviter de copier des données dans des tampons temporels.
Exemple:
Sortie:
la source
IEnumerable<T>
puis ajouter IEnumeratorIEnumerable.GetEnumerator() { return GetEnumerator(); }
Le ArraySegment est BEAUCOUP plus utile que vous ne le pensez. Essayez d'exécuter le test unitaire suivant et préparez-vous à être surpris!
Vous voyez, tout ce que vous avez à faire est de convertir un ArraySegment en IList et il fera toutes les choses que vous attendiez probablement qu'il fasse en premier lieu. Notez que le type est toujours ArraySegment, même s'il se comporte comme une liste normale.
PRODUCTION:
la source
IList<T>
. Je m'attendrais à ce que l'indexeur le soitpublic
.En termes simples: il garde la référence à un tableau, vous permettant d'avoir plusieurs références à une seule variable de tableau, chacune avec une plage différente.
En fait, cela vous aide à utiliser et à transmettre des sections d'un tableau d'une manière plus structurée, au lieu d'avoir plusieurs variables, pour contenir l'index de début et la longueur. Il fournit également des interfaces de collecte pour travailler plus facilement avec les sections de tableau.
Par exemple, les deux exemples de code suivants font la même chose, l'un avec ArraySegment et l'autre sans:
et,
De toute évidence, le premier extrait de code est préférable, en particulier lorsque vous souhaitez transmettre des segments de tableau à une fonction.
la source