Emulering av Memory/ReadOnlyMemory: vinduer uten kopiering
Send inn ArraySegment i stedet for arrayer: opprett vinduer, implementer Skip/Take/Slice, parse headere og nyttelaster, og kopier bare ved grensene.
Emulering av Memory/ReadOnlyMemory: vinduer uten kopiering er en gratis leksjon i C# Academy på CoddyKit. Dette er leksjon 2 av 3. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i C# Academy, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i C# Academy inneholder totalt 3 leksjoner.
Vinduer over arrayer
Mål: Behandle arrayer som minnevinduer.
- Bruk ArraySegment<T> for å sende visninger
- Bygg små Skip/Take/Slice-hjelpere
- Analyser headere og payloads uten kopier
- Kopier bare ved I/O-grenser
Skip/Take/Slice-hjelpere
Lag små Slice-, Skip- og Take-hjelpere for å sette sammen vinduer på en tydelig måte.
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]);
}
}
Kopiering fra vindu til vindu
Bruk Buffer.BlockCopy for å flytte data mellom vinduer uten å opprette nye arrayer.
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 av header + payload
Analyser ved hjelp av offset, og opprett et window for payloaden. Konverter til tekst bare når det er nødvendig.
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));
}
}
Skrivebeskyttet etter konvensjon
Skrivebeskyttet oppførsel er en konvensjon i C# 6 med ArraySegment: ikke endre data i funksjoner som bare lover å lese.
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);
}
}
Kopier ved grensene
Kopier bare ved kanten (når data sendes til et annet lag, logges eller lagres). Hold de indre trinnene uten kopiering.
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));
}
}
Hvorfor vinduer er nyttige
Oppsummering
Oppsummering: Bruk ArraySegment<T> som et minnelignende vindu. Sett sammen med Skip/Take/Slice, analyser ved hjelp av offseter, og kopier bare når De må.
Lær deg C# med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 93
- Leksjoner
- 346
Ofte stilte spørsmål
Er leksjonen «Emulering av Memory/ReadOnlyMemory: vinduer uten kopiering» gratis?
Ja – hele teksten i «Emulering av Memory/ReadOnlyMemory: vinduer uten kopiering» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av C# Academy-kurset, kan du oppgradere til CoddyKit PRO. Kurset i C# Academy inneholder totalt 3 leksjoner.
Hva lærer jeg i «Emulering av Memory/ReadOnlyMemory: vinduer uten kopiering»?
Send inn ArraySegment i stedet for arrayer: opprett vinduer, implementer Skip/Take/Slice, parse headere og nyttelaster, og kopier bare ved grensene. Du øver på C# Academy med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med C# Academy?
Ingen tidligere erfaring er nødvendig. C# Academy på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 3.
Hvor lang tid tar leksjonen «Emulering av Memory/ReadOnlyMemory: vinduer uten kopiering»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne C# Academy-leksjonen?
Ja. Alle C# Academy-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Grunnleggende Span/ReadOnlySpan (C# 6-emulering)
- Emulering av Memory/ReadOnlyMemory: vinduer uten kopiering
- String-som-Span-API-er (C# 6-emulering)