p.212 文字列をインデックスとするインデクサ
・整数ではないインデックスを受け取ってインデクサの中で配列の要素にアクセスする処理を記述することができる
・よって、文字列をインデックスとするインデクサや、実数をインデックスとするインデクサも可能になる
アレンジ演習:p.217 indexer03.cs
・実数をインデックスとするインデクサを追加して、動作を確認しよう
作成例
//アレンジ演習:p.217 indexer03.cs
using System;
class MyIndexer {
string[] mon = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
public int this[string MonthName] { //文字列をインデックスとするインデクサ
get {
for (int i = 0; i < 12; i++) { //配列の全要素について
if (MonthName == mon[i]) { //月名と一致?
return i + 1; //添字+1を返す
}
}
return 0; //一つも一致しなかったら0を返す
}
}
public string this[double n] { //【以下追加】実数をインデックスとするインデクサ
get {
if (n >= 1.0 && n < 13.0) { //1以上13未満であれば
return mon[(int)n - 1]; //整数化して添字にして月名を返す
}
return "";
}
}
}
class indexer03 {
public static void Main() {
MyIndexer mi = new MyIndexer();
Console.WriteLine("Mayは{0}番目の月です", mi["May"]); //5
Console.WriteLine("Decは{0}番目の月です", mi["Dec"]); //12
Console.WriteLine("xは{0}番目の月です", mi["x"]); //0
Console.WriteLine("mi[1.01] = {0}", mi[1.01]); //【追加】"Jan"
Console.WriteLine("mi[12.9] = {0}", mi[12.9]); //【追加】"Dec"
Console.WriteLine("mi[33.3] = {0}", mi[33.3]); //【追加】""
}
}
p.218 多次元のインデクサ
・2つ以上のインデクスを持つインデクサを記述できる
・2次元の書式: データ型 this[インデックス型① インデックス①, インデックス型② インデックス②] { get {…} set {…} }
アレンジ演習:p.219 indexer04.cs
・インデクサのgetにインデックスの範囲チェックを加えよう
・インデックスが不適切な時は""を返す
作成例
//p.219 indexer04.cs
using System;
class MyClass {
string[,] name; //クラス内部でのデータ保持用の2次元配列(参照のみ)
public string this[int i, int j] { //2次元インデクサ
get {
if (i >= 0 && i < 2 && j >= 0 && j < 5) { //【追加】添字が範囲内?
return name[i, j]; //名前を返す
}
return ""; //【追加】範囲外なら空文字列を返す
}
}
public MyClass() { //コンストラクタ
name = new string[,]{{"田中", "佐藤", "吉田", "加藤", "粂井"}, //1組1~5番
{"工藤", "竹中", "斉藤", "太田", "杉本"}}; //2組1~5番
}
}
class indexer04 {
public static void Main() {
MyClass mc = new MyClass();
for (int i = 0; i < 2; i++) { //全組について繰返す
for (int j = 0; j < 5; j++) { //全番について繰返す
Console.WriteLine("{0}組{1}番--{2}", i + 1, j + 1, mc[i, j]);
}
}
Console.WriteLine("{0}組{1}番--{2}", 3, 3, mc[3, 3]); //【追加】
}
}
p.220 インデクサのオーバーロード
・インデクサのシグニチャはインデックスのデータ型と数と並びであり、シグニチャの異なるインデクサを複数記述できる
・これをインデクサのオーバーロードという
アレンジ演習:p.220 indexer05.cs
・インデクサのgetにインデックスの範囲チェックを加えよう
・インデックスが不適切な時は0を返す
・データはintで、インデックスはdoubleであるインデクサを追記しよう
・インデクスの値をintにキャストして、this[int]を呼ぶようにしよう
作成例
//アレンジ演習:p.220 indexer05.cs
using System;
class MyOverLoad {
int[] a = new int[3] { 1, 2, 3 }; //インデクサ①で扱う配列
int[,] b = new int[2, 2] { { 100, 200 }, { 300, 400 } }; //インデクサ②で扱う配列
public int this[int i] { //インデクサ①
get {
if (i >= 0 && i < a.Length) { //【追加】添字として適切かチェック
return a[i]; //インデクサ①で扱う配列の要素値を返す
}
return 0;
}
}
public int this[int i, int j] { //インデクサ②
get {
if (i >= 0 && i < 2 && j >= 0 && j < 2) { //【追加】添字として適切かチェック
return b[i, j]; //インデクサ②で扱う配列の要素値を返す
}
return 0;
}
}
public int this[double i] { //【以下追加】インデクサ③:インデックスが実数
get {
return this[(int)i]; //インデックスを整数化することで、インデクサ①を呼ぶ
}
}
}
class indexer05 {
public static void Main() {
MyOverLoad mo = new MyOverLoad();
for (int i = 0; i < 3; i++) {
Console.WriteLine("mo[{0}] = {1}", i, mo[i]); //インデクサ①を呼ぶ
}
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
Console.WriteLine("mo[{0}, {1}] = {2}", i, j, mo[i, j]); //インデクサ②を呼ぶ
}
}
//【以下追加】
Console.WriteLine("mo[9] = {0}", mo[9]); //インデクサ①を呼ぶ(範囲外なので0)
Console.WriteLine("mo[9,8] = {0}", mo[9, 8]); //インデクサ②を呼ぶ(範囲外なので0)
Console.WriteLine("mo[1.8] = {0}", mo[1.8]); //インデクサ③を呼ぶ
Console.WriteLine("mo[9.8] = {0}", mo[9.8]); //インデクサ③を呼ぶ(範囲外なので0)
}
}
p.222 練習問題1 ヒント
・p.209 prop02.csを単純化すると良い
・double型のデータメンバ1つのみになる
・Mainメソッドで負の数や0を与えて動作を確認すること
作成例
//p.222 練習問題1 ex0801.cs
using System;
class BMI {
double bw; //体重(publicがないのでprivate扱い)
public double bwprop { //体重のプロパティ
get { //プロパティを利用すると実行される内容(無制限)
return bw;
}
set { //プロパティに代入すると実行される内容(制限有り)
if (value <= 0) {
Console.WriteLine("0または負の値は設定できません");
return; //プロパティの途中で呼ばれた相手に戻る
}
bw = value; //代入した値がvalueキーワード経由で渡される
}
}
}
class prop02 {
public static void Main() {
BMI mybmi = new BMI();
mybmi.bwprop = 73.2; //プロパティのsetを用いて代入
Console.WriteLine("bw = {0}", mybmi.bwprop); //プロパティのget実行
mybmi.bwprop = 0.0; //プロパティのsetを用いて代入(無視される)
Console.WriteLine("bw = {0}", mybmi.bwprop); //プロパティのget実行(73.2のまま)
mybmi.bwprop = -1.1; //プロパティのsetを用いて代入(無視される)
Console.WriteLine("bw = {0}", mybmi.bwprop); //プロパティのget実行(73.2のまま)
}
}
p.222 練習問題2 ヒント ex0802.cs
・p.217 indexer03.csをベースにすると良い
・コンストラクタで生徒数を入力する部分は、p.214 indexer02.csが参考になる
・生徒名を格納するstring型配列と、点数を格納するint型配列を宣言して用いると楽
※ 生徒名と点数をメンバとするクラスオブジェクトの配列にできればさらに良い
・要素の生成はコンストラクタで行うと良い
・Mainメソッドで格納結果を表示すること
提出:p.222 練習問題2 ex0802.cs(未完成でもOK)