C#メモ
デリゲート
メソッド専用のインタフェースみたいなもの
戻り値と引数がデリゲート宣言と一致していれば、デリゲート変数に代入することができる。
delegate string StrMod(string str);
public string ReplaceSpaces(string a) {
retunr a.Replace(' ', '-');
}
static void Main() {
StrMod strOp = ReplaceSpaces;
strOp("test");
}
デリゲートのマルチキャスト
デリゲートは連鎖することができる。(デリゲートのマルチキャスト)
using System;
delegate void StrMod(ref string str);
class StringOps
{
static void ReplacesSpaces(ref string a)
{
a = a.Replace(' ', '-');
}
static void Reverse(ref string a)
{
string temp = "";
int i, j;
for (j = 0, i = a.Length - 1; i >= 0; i--, j++)
{
temp += a[i];
}
a = temp;
}
static void Main()
{
StrMod strOp;
strOp = ReplacesSpaces;
strOp += Reverse;
var str = "This is a test";
Console.WriteLine(str);
strOp(ref str);
Console.WriteLine(str);
}
}
デリゲートを使用する理由
デリゲート変数に代入されるメソッドはコンパイル時ではなく、実行時に決定される。そのため、プラグインなどの開発に利用できる。
匿名メソッド
delegate void CountIt();
CountIt count = delegate {
//処理
}
delegate void CountIt(int i);
CountIt = delegate (int end) {
//処理
}
// 匿名メソッドは値を返すこともできる。
delegate int CountIt(int i);
CountIt = delegate (int end) {
int result;
//処理
return result;
}
キャプチャ
匿名メソッドを囲んでいるスコープの変数にアクセスすることができる。この変数は匿名メソッドにキャプチャされていると言う。匿名メソッドを参照しているデリゲートインスタンスがGC されるまで、キャプチャされたインスタンスはGCされない。
int hogehoge;
delegate int CountIt(int i);
CountIt = delegate (int end) {
int result;
result += hogehoge; //hogehogeにアクセスすることができる。hogehogeはキャプチャされている。
//処理
return result;
}
イベント
リスナーの登録にデリゲートを利用することができる。
ただし、複数のリスナーをマルチキャスト登録されることは問題ないが、イベントハンドラーの参照を意図せず変更されることは避けたい。
そんため、デリゲートをマルチキャストの使用に制限するeventが存在する。
イベント送信側のクラス(イベントハンドラー)
delegate void MyEventHandler();
class MyEventHandler {
public event MyEventHandler SomeEvent; // リスナーはこの変数にイベント発生時の処理を登録する。
}
名前空間
名前空間が指定されていないとグローバル名前空間に変数やメソッドが登録される。
namespace 名前空間名 {
//以下の記述は全て名前空間に含まれる。
}
既存の名前空間や型に別名を付けることもできる。
using エイリアス = 名前;
同一の名前空間ブロックが複数ファイルに存在しても構わない。これらは一つの名前空間として扱われる。ただし、これらは同時にコンパイルする必要がある。
名前空間はネストすることができる。この場合ネストされた名前空間には.
で繋いでアクセスすることができる。
名前空間エイリアス修飾子
using alpha = Alpha.Utility;
alpha.MyClass
//alphaという名前空間が存在し、その中にMyClassが存在すると競合する。
//alphaは名前空間ではなくエイリアスであることを明記したい。
alpha::MyClass//::を利用することで、alphaがエイリアスであることが明記される。