インデクサー (this[])
CoddyのC#ジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 37/70。
インデクサーを使用すると、配列のようなブラケット記法を使用してクラス内の要素にアクセスできます。collection.GetItem(0) のようなメソッドを呼び出す代わりに、より直感的な collection[0] と書くことができます。
インデクサーを定義するには、this キーワードと角括弧を使用します:
public class Sentence
{
private string[] words;
public Sentence(string text)
{
words = text.Split(' ');
}
public string this[int index]
{
get { return words[index]; }
set { words[index] = value; }
}
}これで、自然に単語にアクセスできるようになります:
Sentence s = new Sentence("Hello World");
Console.WriteLine(s[0]); // Hello
s[1] = "C#";
Console.WriteLine(s[1]); // C#インデクサーは整数に限定されません。任意の型をインデックスパラメータとして使用できるため、辞書のようなアクセスに便利です。
public string this[string key]
{
get { return dictionary[key]; }
set { dictionary[key] = value; }
}プロパティと同様に、インデクサーは読み取り専用にしたり(setterを省略する)、アクセサーに検証ロジックを含めたりすることができます。これらは、クラスがコレクションをラップしている場合や、ブラケット記法によってコードの可読性が向上する場合に最適です。
チャレンジ
簡単配列を扱うのと同じように、直感的なブラケット記法を使用して曲にアクセスできる Playlist クラスを作成しましょう。インデクサーを使用して、曲の位置(インデックス)によって曲を取得および更新できるミュージックプレイリストを作成します。
コードは2つのファイルに分けて構成します:
Playlist.cs:Music名前空間内にPlaylistクラスを作成します。このクラスは内部で曲のコレクションを保持し、インデクサーを通じて配列のようなアクセスを提供します。プレイリストには以下の要素を含めてください:- 曲のタイトルを格納するためのプライベートな文字列配列
- カンマ区切りの曲タイトルの文字列を受け取り、それを内部配列に分割して格納するコンストラクター
- 特定の位置にある曲の取得と設定の両方を可能にする、
this[int index]を使用したインデクサー - プレイリスト内の曲数を返す読み取り専用プロパティ
Count - すべての曲を
" | "で結合して返すメソッドGetAllSongs()
Program.cs: メインファイルで、入力からプレイリストを作成し、インデクサーを使用して曲にアクセスおよび変更を行います。インデックスによる曲の読み取りと、特定の位置にある曲の更新の両方を実演してください。
3つの入力を受け取ります:
- カンマ区切りの曲タイトルのリスト(例:
Song A,Song B,Song C) - 取得するインデックス(整数)
- その同じインデックスにある曲を置き換えるための新しい曲のタイトル
以下の形式で出力を表示してください:
Total songs: {Count}
Song at index {index}: {song title}
After update: {GetAllSongs()}例えば、入力が Rock Anthem,Jazz Vibes,Pop Hit、1、Blues Classic の場合、出力は以下のようになります:
Total songs: 3
Song at index 1: Jazz Vibes
After update: Rock Anthem | Blues Classic | Pop Hitインデクサーを使用することで、playlist[1] で "Jazz Vibes" を取得し、playlist[1] = "Blues Classic" と代入して更新できることに注目してください。これは GetSongAt(1) や SetSongAt(1, "Blues Classic") のようなメソッドを呼び出すよりも、はるかに自然です!
チートシート
インデクサーを使用すると、メソッド呼び出しの代わりに、配列のようなブラケット記法(collection[0])を使用してクラス内の要素にアクセスできるようになります。
インデクサーを定義するには、thisキーワードと角括弧を使用します。
public class Sentence
{
private string[] words;
public Sentence(string text)
{
words = text.Split(' ');
}
public string this[int index]
{
get { return words[index]; }
set { words[index] = value; }
}
}使用例:
Sentence s = new Sentence("Hello World");
Console.WriteLine(s[0]); // Hello
s[1] = "C#";
Console.WriteLine(s[1]); // C#インデクサーは、整数だけでなく、任意の型をインデックスパラメータとして使用できます。
public string this[string key]
{
get { return dictionary[key]; }
set { dictionary[key] = value; }
}プロパティと同様に、インデクサーを読み取り専用にしたり(セッターを省略)、アクセサー内にバリデーションロジックを含めたりすることができます。
自分で試してみよう
using System;
using Music;
class Program
{
public static void Main(string[] args)
{
// 入力を読み込む
string songList = Console.ReadLine();
int index = Convert.ToInt32(Console.ReadLine());
string newSong = Console.ReadLine();
// TODO: songList から Playlist オブジェクトを作成する
// TODO: Count プロパティを使用して曲の総数を表示する
// TODO: インデクサを使用して、指定されたインデックスにある曲を表示する
// TODO: インデクサを使用して、指定されたインデックスにある曲を更新する
// TODO: GetAllSongs() を使用して、更新後のすべての曲を表示する
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。