0Pricing
C# Academy · レッスン

インデクサー

配列のような構文でオブジェクトにアクセスします。

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

インデクサーとは

インデクサーを使うと、配列のように [ ] 構文でオブジェクトにアクセスできます。this[...] を使って定義します。コレクションのように扱うクラスに最適です。

using System;

class Week
{
    private string[] _days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };

    public string this[int index] => _days[index];
}

class Program
{
    static void Main()
    {
        var w = new Week();
        Console.WriteLine(w[0]);
        Console.WriteLine(w[6]);
    }
}

インデクサーの構文

インデクサーはプロパティに似ていますが、this を使用し、角かっこ内にパラメーターリストを指定します。get を持ち、必要に応じて set も持ちます。

using System;

class Scores
{
    private int[] _data = new int[5];

    public int this[int i]
    {
        get { return _data[i]; }
        set { _data[i] = value; }
    }
}

class Program
{
    static void Main()
    {
        var s = new Scores();
        s[0] = 90;
        s[1] = 75;
        Console.WriteLine(s[0] + ", " + s[1]);
    }
}

インデクサーによる読み書き

getter と setter の両方を指定すると、クラスが基になる保存領域を制御しながら、配列と同じように要素を代入したり読み取ったりできます。

using System;

class Grid
{
    private int[] _cells = new int[3];

    public int this[int i]
    {
        get => _cells[i];
        set => _cells[i] = value;
    }
}

class Program
{
    static void Main()
    {
        var g = new Grid();
        for (int i = 0; i < 3; i++) g[i] = i * 10;
        Console.WriteLine(g[0] + ", " + g[1] + ", " + g[2]);
    }
}

インデクサーでの検証

インデクサーは通常のコードなので、インデックスを検証し、範囲外へのアクセスに対してわかりやすいエラーをスローできます。

using System;

class SafeList
{
    private int[] _data = new int[3];

    public int this[int i]
    {
        get
        {
            if (i < 0 || i >= _data.Length)
                throw new IndexOutOfRangeException("Bad index: " + i);
            return _data[i];
        }
        set { _data[i] = value; }
    }
}

class Program
{
    static void Main()
    {
        var list = new SafeList();
        list[1] = 42;
        Console.WriteLine(list[1]);
    }
}

文字列キーのインデクサー

インデクサーのパラメーターは int に限りません。string キーを使うと、クラスを辞書のような検索に利用できます。

using System;
using System.Collections.Generic;

class Config
{
    private Dictionary<string, string> _map = new Dictionary<string, string>();

    public string this[string key]
    {
        get => _map.ContainsKey(key) ? _map[key] : "(none)";
        set => _map[key] = value;
    }
}

class Program
{
    static void Main()
    {
        var c = new Config();
        c["theme"] = "dark";
        Console.WriteLine(c["theme"]);
        Console.WriteLine(c["missing"]);
    }
}

複数のパラメーター

インデクサーには複数のパラメーターを指定できます。matrix[row, col] のようにアクセスする行列や 2D グリッドに適しています。

using System;

class Matrix
{
    private int[,] _data = new int[2, 2];

    public int this[int row, int col]
    {
        get => _data[row, col];
        set => _data[row, col] = value;
    }
}

class Program
{
    static void Main()
    {
        var m = new Matrix();
        m[0, 0] = 1;
        m[1, 1] = 9;
        Console.WriteLine(m[0, 0] + ", " + m[1, 1]);
    }
}

読み取り専用インデクサー

setter を省略すると読み取り専用インデクサーになり、外部からの変更を許可せずにデータを公開できます。

using System;

class Fibonacci
{
    public int this[int n]
    {
        get
        {
            int a = 0, bv = 1;
            for (int i = 0; i < n; i++)
            {
                int t = a + bv;
                a = bv;
                bv = t;
            }
            return a;
        }
    }
}

class Program
{
    static void Main()
    {
        var fib = new Fibonacci();
        Console.WriteLine(fib[7]);
    }
}

インデクサーとプロパティの違い

プロパティには名前(obj.Name)でアクセスし、インデクサーにはキー(obj[key])でアクセスします。オブジェクトをコレクションのように扱う場合はインデクサーを使用してください。

using System;

class Inventory
{
    private int[] _stock = new int[4];
    public int Total => _stock.Length;          // property
    public int this[int slot]                    // indexer
    {
        get => _stock[slot];
        set => _stock[slot] = value;
    }
}

class Program
{
    static void Main()
    {
        var inv = new Inventory();
        inv[2] = 15;
        Console.WriteLine("Slot 2: " + inv[2] + ", Total slots: " + inv.Total);
    }
}

オーバーロードされたインデクサー

パラメーターの型が異なる複数のインデクサーを定義でき、コンパイラーが引数に一致するものを選択します。

using System;
using System.Collections.Generic;

class People
{
    private List<string> _names = new List<string> { "Ann", "Bob", "Cara" };

    public string this[int i] => _names[i];
    public int this[string name] => _names.IndexOf(name);
}

class Program
{
    static void Main()
    {
        var p = new People();
        Console.WriteLine(p[1]);
        Console.WriteLine(p["Cara"]);
    }
}

インデックス付きオブジェクトの反復処理

インデクサーと個数を表すプロパティを組み合わせると、カスタムコレクションを自然にループ処理できます。

using System;

class Ring
{
    private int[] _data = { 10, 20, 30 };
    public int Count => _data.Length;
    public int this[int i] => _data[i % _data.Length];
}

class Program
{
    static void Main()
    {
        var ring = new Ring();
        for (int i = 0; i < 5; i++)
            Console.Write(ring[i] + " ");
        Console.WriteLine();
    }
}

全体を組み立てる

インデクサーを使うと、ラッパークラスをネイティブコレクションのように扱えるようになり、使い慣れた角かっこ構文の背後に保存方法の詳細を隠せます。

using System;
using System.Collections.Generic;

class Phonebook
{
    private Dictionary<string, string> _book = new Dictionary<string, string>();

    public string this[string name]
    {
        get => _book.TryGetValue(name, out var num) ? num : "unknown";
        set => _book[name] = value;
    }
}

class Program
{
    static void Main()
    {
        var pb = new Phonebook();
        pb["Alice"] = "555-1234";
        Console.WriteLine("Alice: " + pb["Alice"]);
        Console.WriteLine("Zed: " + pb["Zed"]);
    }
}

理解度チェック

インデクサーについて理解できているか確認しましょう。

まとめ

インデクサーは this[...] を使い、クラスに配列のようなアクセスを提供します。get/set、int や string などの任意のパラメーター型、複数パラメーター、検証、オーバーロード、読み取り専用形式に対応できます。コレクションのように扱うクラスにはインデクサーを使い、個別の属性には名前付きプロパティを使用してください。

using System;

class Demo
{
    private int[] _v = new int[3];
    public int this[int i]
    {
        get => _v[i];
        set => _v[i] = value;
    }
}

class Program
{
    static void Main()
    {
        var d = new Demo();
        d[0] = 100;
        Console.WriteLine(d[0]);
    }
}

よくある質問

「インデクサー」レッスンは無料ですか?

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

「インデクサー」で何を学びますか?

配列のような構文でオブジェクトにアクセスします。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

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

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

「インデクサー」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

  1. 自動実装プロパティ
  2. バッキングフィールドを持つ完全なプロパティ
  3. 式形式のメンバー
  4. インデクサー
← C# Academyに戻る