インデクサー
配列のような構文でオブジェクトにアクセスします。
「インデクサー」は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フィードバックを取得できます。ローカル設定は不要です。