p.174 this
・自分自身を指す参照を与えるキーワードがthis ・(テキストのサンプルは文法説明にしかなっていないが)クラスの中で自分自身を指す参照を操作に利用できる
p.174 this01.cs
//p.174 this01.cs
using System;
class MyClass {
public MyClass m1, m2; //自クラスを型とするフィールド
public void Test() {
m2 = this; //自クラス型なので自分への参照を代入できる
}
public MyClass() { //コンストラクタ
m1 = this; //自クラス型なので自分への参照を代入できる
}
}
class this01 {
public static void Main() {
MyClass mc = new MyClass(); //コンストラクタが呼ばれ、m1にthisが代入される
mc.Test(); //メソッドが呼ばれ、m2にthisが代入される
if (mc.m1 == mc.m2)
Console.WriteLine("m1とm2は同じです");
if (mc == mc.m1) //mcは自オブジェクトなのでm1、m2と同じ
Console.WriteLine("mcとm1は同じです");
if (mc == mc.m2) //同上
Console.WriteLine("mcとm2は同じです");
}
}
補足:thisの活用法① 自オブジェクトのデータを書き換えた結果を返すメソッド
・thisを使わずに自分のHPを倍にすると、単独で実行するしかない
class Monster {
public int hp;
public void hpx2() { hp = hp * 2; }
}
:
Monster slalin = new Monster();
slalin.hp = 100;
slalin.hpx2(); //200になる
slalin.hpx2(); //400になる
slalin.hpx2(); //800になる
Console.WriteLine(slalin.hp);
・thisを使って自分のHPを倍にすると、メソッドの結果をメソッドに渡すことで効率化できる
class Monster {
public int hp;
public Monster hpx2() { hp = hp * 2; return this; } //HPを2倍し、自分への参照を返す
}
:
Monster slalin = new Monster();
slalin.hp = 100;
slalin.hpx2().hpx2().hpx2(); //800になる
Console.WriteLine(slalin.hp);
・応用例
using System;
class Monster {
public int hp, mp;
public Monster hpx2() { hp = hp * 2; return this; }
public Monster mpx2() { mp = mp * 2; return this; }
}
class this01 {
public static void Main() {
Monster slalin = new Monster();
slalin.hp = 100;
slalin.mp = 150;
slalin.hpx2().hpx2().hpx2().mpx2(); //HPは800、MPは300になる
Console.WriteLine("{0},{1}", slalin.hp, slalin.mp);
}
}
補足:thisの活用法② インスタンス変数を用いるメソッドやコンストラクタの引数名を変数名と同じにできる
・下記のように「this.」はインスタンス変数、そうでない方は引数。
class Monster {
public int hp, mp;
public Monster(int hp) { this.hp = hp; }
public void addmp(int mp) { this.mp += mp; }
}
※ この記述スタイルの利用をチームルールにしている場合もある
p.176 既存のクラスを使ってみる
・C#が提供するArrayListクラスには、コンストラクタやインスタンス変数、インスタンスメソッドなどがある https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.arraylist ・ArrayListクラスは必要に応じてサイズが動的に拡大されるArrayList配列を提供してくれる ・利用には、using System.Collections; を指定すると良い ・ArrayList配列の生成は、ArrayListクラスのデフォルトコンストラクタを呼ぶだけで良い(生成時の型指定は不要) ・ArrayList配列への要素の格納は、参照変数.Add(要素) で良く、要素の型は自由 ・ArrayList配列の要素は配列と同様に 参照変数[添字] で直接扱える。 ・ただし、型情報を失っているので、計算などにはキャストしてから扱うこと ・ArrayList配列の要素数は、参照変数.Count で得られる(プロパティ(p.207))
p.177 arraylist01.cs
//p.177 arraylist01.cs
using System;
using System.Collections;
class arraylist01 {
public static void Main() {
bool bEnd = false; //終了フラグをオフにする
string strData; //入力用
double sum = 0.0; //合計
ArrayList al = new ArrayList(); //ArrayList配列を生成
while (true) { //無限ループ
Console.Write("データ(数値以外入力で終了)-- ");
strData = Console.ReadLine();
if (!Char.IsDigit(strData[0]) && strData[0] != '-') { //先頭文字が数字でなく-でもない?
bEnd = true; //終了フラグをオンにする
} else {
al.Add(double.Parse(strData)); //ArrayList配列に格納
}
if (bEnd) { //終了フラグがオン?
break; //ループを抜ける
}
}
for (int i = 0; i < al.Count; i++) { //ArrayList配列の全データについて繰返す
Console.WriteLine("Data[{0}] = {1}", i + 1, al[i]);
sum += (double)al[i]; //実数に戻して合計に足し込む
}
int count = al.Count; //ArrayList配列の要素数を得る
double avr = sum / count; //合計を割って平均値を得る
Console.WriteLine("データ個数 = {0}", count);
Console.WriteLine("平均値 = {0}", avr);
}
}
提出:アレンジ演習:p.177 arraylist01.cs
・終了フラグを用いないようにしよう ・foreachが利用できるか試してみよう
p.180 練習問題1 ヒント
・クラス定義の例: class MyClass { public int n; }
p.180 練習問題2 ヒント
・int型とint型の和を求めるメソッドの戻り値型はint型にすると良い ・double型とdouble型の和を求めるメソッドの戻り値型はdouble型にすると良い ・上記はMainメソッドから利用するので、publicにすると良い