0Pricing
C# Academy · Leçon

Émulation de Memory/ReadOnlyMemory : fenêtres sans copie

Transmettez ArraySegment plutôt que des tableaux : créez des fenêtres, implémentez Skip/Take/Slice, analysez les en-têtes et les charges utiles et ne copiez les données qu’aux limites.

Émulation de Memory/ReadOnlyMemory : fenêtres sans copie est une leçon C# Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 3. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C# Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C# Academy comprend 3 leçons au total.

Fenêtres sur des tableaux

Objectif : considérer les tableaux comme des fenêtres mémoire.

  • Utilisez ArraySegment<T> pour transmettre des vues
  • Créez de petits assistants Skip/Take/Slice
  • Analysez les en-têtes et les charges utiles sans copies
  • Ne copiez qu’aux frontières des entrées-sorties

Assistants Skip/Take/Slice

Créez de petits assistants Slice, Skip et Take pour composer clairement les fenêtres.

using System;

public static class Seg
{
  public static ArraySegment<T> Slice<T>(ArraySegment<T> s, int start, int count)
  {
    if (start < 0 || count < 0 || start + count > s.Count) throw new ArgumentOutOfRangeException();
    return new ArraySegment<T>(s.Array, s.Offset + start, count);
  }

  public static ArraySegment<T> Skip<T>(ArraySegment<T> s, int n)
  {
    if (n < 0 || n > s.Count) throw new ArgumentOutOfRangeException("n");
    return new ArraySegment<T>(s.Array, s.Offset + n, s.Count - n);
  }

  public static ArraySegment<T> Take<T>(ArraySegment<T> s, int n)
  {
    if (n < 0 || n > s.Count) throw new ArgumentOutOfRangeException("n");
    return new ArraySegment<T>(s.Array, s.Offset, n);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    int[] xs = new int[] { 10, 20, 30, 40, 50 };
    ArraySegment<int> view = new ArraySegment<int>(xs, 1, 3); // 20,30,40
    ArraySegment<int> head = Seg.Take<int>(view, 2);          // 20,30
    ArraySegment<int> tail = Seg.Skip<int>(view, 1);          // 30,40
    Console.WriteLine(head.Array[head.Offset] + "," + head.Array[head.Offset + 1]);
    Console.WriteLine(tail.Array[tail.Offset] + "," + tail.Array[tail.Offset + 1]);
  }
}

Copie d’une fenêtre à l’autre

Utilisez Buffer.BlockCopy pour déplacer les données entre les fenêtres sans créer de nouveaux tableaux.

using System;

public static class SegCopy
{
  public static int Copy(ArraySegment<byte> src, ArraySegment<byte> dst)
  {
    int n = src.Count < dst.Count ? src.Count : dst.Count;
    Buffer.BlockCopy(src.Array, src.Offset, dst.Array, dst.Offset, n);
    return n;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    byte[] a = new byte[] { 1, 2, 3, 4, 5, 6 };
    byte[] b = new byte[] { 0, 0, 0, 0, 0, 0 };

    ArraySegment<byte> winA = new ArraySegment<byte>(a, 2, 3); // 3,4,5
    ArraySegment<byte> winB = new ArraySegment<byte>(b, 1, 3); // target

    int copied = SegCopy.Copy(winA, winB);
    Console.WriteLine("Copied: " + copied);
    Console.WriteLine(string.Join(",", b)); // 0,3,4,5,0,0
  }
}

Analyse de l’en-tête et de la charge utile

Analysez les données à partir du décalage et créez une fenêtre pour la charge utile. Convertissez-la en texte uniquement lorsque cela est nécessaire.

using System;
using System.Text;

public static class Parser
{
  // Message layout: [len:2 bytes little-endian][type:1 byte][payload:len bytes]
  public static void Parse(ArraySegment<byte> msg)
  {
    if (msg.Count < 3) throw new ArgumentException("message too short");

    int o = msg.Offset;
    byte[] arr = msg.Array;

    int len = arr[o] | (arr[o + 1] << 8); // ushort little-endian
    byte typ = arr[o + 2];

    ArraySegment<byte> payload = new ArraySegment<byte>(arr, o + 3, len);
    Console.WriteLine("Type=" + typ + " Len=" + len);

    // Materialize only at the boundary (to string for display)
    string text = Encoding.ASCII.GetString(payload.Array, payload.Offset, payload.Count);
    Console.WriteLine("Payload: " + text);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    // Build: len=5 ("Hello"), type=42
    byte[] buf = new byte[3 + 5];
    buf[0] = 5; buf[1] = 0; buf[2] = 42;
    byte[] hello = Encoding.ASCII.GetBytes("Hello");
    Buffer.BlockCopy(hello, 0, buf, 3, 5);

    Parser.Parse(new ArraySegment<byte>(buf, 0, buf.Length));
  }
}

Lecture seule par convention

Avec ArraySegment en C# 6, le comportement en lecture seule repose sur une convention : ne modifiez jamais les données dans les fonctions qui promettent de se limiter à la lecture.

using System;

public static class Checksums
{
  // Treat the segment as "read-only": never write to seg.Array here.
  public static int SumBytes(ArraySegment<byte> seg)
  {
    int end = seg.Offset + seg.Count;
    int total = 0;
    for (int i = seg.Offset; i < end; i++) total += seg.Array[i];
    return total & 0xFF;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    byte[] data = new byte[] { 10, 20, 30, 40, 50 };
    ArraySegment<byte> window = new ArraySegment<byte>(data, 1, 3); // 20,30,40
    int checksum = Checksums.SumBytes(window);
    Console.WriteLine("Checksum = " + checksum);
  }
}

Copier aux frontières

Ne copiez qu’à la frontière, par exemple lors de l’envoi vers une autre couche, de la journalisation ou du stockage. Conservez les étapes internes sans copie.

using System;

public static class Materialize
{
  public static T[] ToArray<T>(ArraySegment<T> s)
  {
    T[] copy = new T[s.Count];
    Array.Copy(s.Array, s.Offset, copy, 0, s.Count);
    return copy;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    int[] data = new int[] { 5, 6, 7, 8, 9 };
    ArraySegment<int> middle = new ArraySegment<int>(data, 1, 3); // 6,7,8
    int[] copy = Materialize.ToArray<int>(middle); // copy at boundary
    Console.WriteLine(string.Join(",", copy));
  }
}

Pourquoi les fenêtres sont utiles

Vérification rapide : pourquoi transmettre ArraySegment<byte> à un analyseur plutôt que byte[] ?

Récapitulatif

Récapitulatif : utilisez ArraySegment<T> comme une fenêtre similaire à Memory. Composez-la avec Skip/Take/Slice, analysez les données à partir des décalages et ne copiez que lorsque c’est indispensable.

Questions Fréquemment Posées

La leçon « Émulation de Memory/ReadOnlyMemory : fenêtres sans copie » est-elle gratuite ?

Oui — le texte complet de « Émulation de Memory/ReadOnlyMemory : fenêtres sans copie » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C# Academy, passe à CoddyKit PRO. Le cours C# Academy comprend 3 leçons au total.

Qu'est-ce que j'apprendrai dans « Émulation de Memory/ReadOnlyMemory : fenêtres sans copie » ?

Transmettez ArraySegment plutôt que des tableaux : créez des fenêtres, implémentez Skip/Take/Slice, analysez les en-têtes et les charges utiles et ne copiez les données qu’aux limites. Tu pratiques C# Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer C# Academy ?

Aucune expérience préalable n'est requise. C# Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 3.

Combien de temps prend la leçon « Émulation de Memory/ReadOnlyMemory : fenêtres sans copie » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon C# Academy ?

Oui. Chaque leçon C# Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Principes fondamentaux de Span/ReadOnlySpan (émulation en C# 6)
  2. Émulation de Memory/ReadOnlyMemory : fenêtres sans copie
  3. API chaîne-comme-Span (émulation en C# 6)
← Retour à C# Academy