0Pricing
C# Academy · レッスン

文字列をSpanとして扱うAPI(C# 6でのエミュレーション)

文字列をSpanとして扱う方法を再現します。char[]に変換し、ArraySegment でスライスし、インデックスで検索・トリム・解析を行い、部分文字列の作成は端の処理に限ります。

「文字列をSpanとして扱うAPI(C# 6でのエミュレーション)」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン3/3です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全3レッスンが含まれています。

計画: 文字列をスライスとして扱う

目的: C# 6でstring-as-spanの考え方を使います。

  • 一度だけchar[]に変換します
  • ビューとしてArraySegment<char>を使います
  • インデックスでトリミング、検索、解析を行います
  • 境界でのみSubstringします

文字列上のウィンドウ

文字列を一度だけchar[]に変換して、その上にウィンドウを作成し、offset/countで処理します。

using System;

public static class StrWin
{
  public static ArraySegment<char> Window(string s, int start, int count)
  {
    if (s == null) throw new ArgumentNullException("s");
    if (start < 0 || count < 0 || start + count > s.Length) throw new ArgumentOutOfRangeException();
    // Convert once: keep char[] for further operations
    char[] buf = s.ToCharArray();
    return new ArraySegment<char>(buf, start, count);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    string text = "  [User: Ada]  ";
    ArraySegment<char> mid = StrWin.Window(text, 2, 10); // "[User: Ada]"
    Console.WriteLine("Offset=" + mid.Offset + " Count=" + mid.Count);
  }
}

インデックスによるトリミング

インデックスで操作してSpanベースのTrimロジックを再現します。新しい文字列は作成されません。

using System;

public static class SegText
{
  public static ArraySegment<char> Trim(ArraySegment<char> seg)
  {
    int i = seg.Offset;
    int j = seg.Offset + seg.Count - 1;
    while (i <= j && Char.IsWhiteSpace(seg.Array[i])) i++;
    while (j >= i && Char.IsWhiteSpace(seg.Array[j])) j--;
    int n = (j >= i) ? (j - i + 1) : 0;
    return new ArraySegment<char>(seg.Array, i, n);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    char[] buf = "   Hello, Ada   ".ToCharArray();
    ArraySegment<char> all = new ArraySegment<char>(buf, 0, buf.Length);
    ArraySegment<char> t = SegText.Trim(all);

    // Print without creating a new string
    for (int k = 0; k < t.Count; k++) Console.Write(t.Array[t.Offset + k]);
    Console.WriteLine();
  }
}

ウィンドウ内の検索

IndexOfのような小さなヘルパーを作成し、ウィンドウ内の相対位置を返します。

using System;

public static class SegSearch
{
  // Find the first index of a char inside the segment; returns -1 if not found.
  public static int IndexOf(ArraySegment<char> seg, char needle)
  {
    int end = seg.Offset + seg.Count;
    for (int i = seg.Offset; i < end; i++)
      if (seg.Array[i] == needle) return i - seg.Offset; // relative index
    return -1;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    char[] buf = "[User: Ada]".ToCharArray();
    ArraySegment<char> w = new ArraySegment<char>(buf, 0, buf.Length);
    int pos = SegSearch.IndexOf(w, '/'); // 5
    Console.WriteLine("pos=" + pos);
  }
}

ウィンドウからの解析

部分文字列を作成せず、ウィンドウから数値を直接解析し、成功または失敗を返します。

using System;

public static class SegParse
{
  // Try to parse a non-negative integer from the segment; returns false on failure.
  public static bool TryParseInt(ArraySegment<char> seg, out int value)
  {
    value = 0;
    if (seg.Count == 0) return false;
    int end = seg.Offset + seg.Count;
    for (int i = seg.Offset; i < end; i++)
    {
      char c = seg.Array[i];
      if (c < '0' || c > '9') return false;
      int digit = (int)(c - '0');
      // basic overflow-safe step for small inputs
      if (value > (Int32.MaxValue - digit) / 10) return false;
      value = value * 10 + digit;
    }
    return true;
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    char[] buf = "id=1203; name=Ada".ToCharArray();
    ArraySegment<char> idSeg = new ArraySegment<char>(buf, 3, 4); // "1203"
    int n;
    bool ok = SegParse.TryParseInt(idSeg, out n);
    Console.WriteLine(ok ? ("n=" + n) : "parse failed");
  }
}

境界での実体化

新しいstringの作成は最後の手順(UIやログ出力)でのみ行い、内部の処理ではメモリ割り当てを発生させません。

using System;

public static class SegToString
{
  public static string ToStringSegment(ArraySegment<char> seg)
  {
    // Materialize a new string only when needed (e.g., logging/output)
    return new string(seg.Array, seg.Offset, seg.Count);
  }
}

public class Program
{
  public static void Main(string[] args)
  {
    char[] buf = "  key=value  ".ToCharArray();
    ArraySegment<char> all = new ArraySegment<char>(buf, 0, buf.Length);

    // Trim first
    int i = all.Offset, j = all.Offset + all.Count - 1;
    while (i <= j && Char.IsWhiteSpace(buf[i])) i++;
    while (j >= i && Char.IsWhiteSpace(buf[j])) j--;
    ArraySegment<char> trimmed = new ArraySegment<char>(buf, i, (j >= i) ? (j - i + 1) : 0);

    // Create string only at the end
    Console.WriteLine(SegToString.ToStringSegment(trimmed)); // "key=value"
  }
}

String-as-spanアプローチ

確認問題: C# 6で、追加のメモリ割り当てなしに文字列の一部を解析するにはどうすればよいですか?

振り返り

振り返り: 文字列をspanのように扱います。char[]のウィンドウ上で処理し、トリミング、検索、解析にはoffset/countを使い、必要なときだけ実体化します。

よくある質問

「文字列をSpanとして扱うAPI(C# 6でのエミュレーション)」レッスンは無料ですか?

はい。「文字列をSpanとして扱うAPI(C# 6でのエミュレーション)」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全3レッスンが含まれています。

「文字列をSpanとして扱うAPI(C# 6でのエミュレーション)」で何を学びますか?

文字列をSpanとして扱う方法を再現します。char[]に変換し、ArraySegment でスライスし、インデックスで検索・トリム・解析を行い、部分文字列の作成は端の処理に限ります。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/3です。

「文字列をSpanとして扱うAPI(C# 6でのエミュレーション)」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. Span/ReadOnlySpanの基礎(C# 6でのエミュレーション)
  2. Memory/ReadOnlyMemoryのエミュレーション:ゼロコピーのウィンドウ
  3. 文字列をSpanとして扱うAPI(C# 6でのエミュレーション)
← C# Academyに戻る