モチベーションも大事だと思うので覚書として使用します。 ちょうど十週間突破したので、何週間表示はやめようと思います。あと
十週目の感想
既存
という字はきそん
と本来いうらしいです。てことは現存
はげんそん
か…
#イベント
イベントは、GUI(グラフィカルユーザインタフェース)におけるユーザ入力やクリックの事。
何が起こったら(イベント)どうする(イベントハンドラ)。
使用には、
①デリゲート
Delegateか中にAction(どちらもDelegate(メソッド参照))作る。
②イベントフィールド
最初のクラスをイベントフィールドとする
(event
宣言(先程のデリゲートを宣言のターゲットにする(イベントハンドラがあるメソッド呼び出し可能にするため)
と条件(if(EventName !=null)EventName(引数);)も作成)
③イベントハンドラ
2.3個目のクラスに呼び出すメソッド作成(イベントハンドラ内容)
③Main
イベ名 += new デリ名(実行メソッド)
event発生時実行文EventName();
※呼出は抽象的ならオーバーライド(上書き)(引数同じ)メソッド使ってもいい
例外処理としてデリゲートで各メソッド呼び出して発生(本来トリガーif)
class MyEvent
{
//public Action MyDelegate;
public event MyDelegate EventName;
public void OnEventName()
{
if (EventName != null)// null例外
EventName();//イベント発生
}
}
class MyClass
{
public void Show()
{
Console.Write(1);
}
}
class MyClass2
{
public void Show2()
{
Console.Write(2);
}
}
class Event1
{
public static void Main()
{
MyClass mc = new MyClass();
MyClass2 mc2 = new MyClass2();
MyEvent me = new MyEvent();
// イベントハンドラ
me.EventName += new MyDelegate(mc.Show);
me.EventName += new MyDelegate(mc2.Show2);
//me.EventName += () => mc2.Show2; λでスリム
me.OnEventName();//イベント発生
}
}
クラスに分割してデリゲートでイベント(一桁加算機)
// 何かデリゲートの学習してるみたいだけど、元来のイベント処理手順がわかった。
using System;
// 1.delegate
delegate void Handler(char ch);
// 2.field
class EventClass
{
public event Handler KeyHit;
public void OnKeyHit(char ch)
{
if (KeyHit != null)
KeyHit(ch);
}
}
// 3.handler
class Show
{
int sum = 0;
public void KeyShow(char ch)
{
if (Char.IsDigit(ch))
{
int a = (int)char.GetNumericValue(ch);
sum += a;
Console.Write($"+{a}\n");
Console.Write($"={sum}\n");
}
else if (ch == 'c')
{
sum = 0;
Console.Write("合計がクリアされました\n");
}
else return;
}
}
// 4.Main
class Event2
{
public static void Main()
{
ConsoleKeyInfo cki;
EventClass ec = new EventClass();
Show s = new Show();
ec.KeyHit += new Handler(s.KeyShow);
while (true)
{
if (Console.KeyAvailable)
{
cki = Console.ReadKey(true);
if (cki.KeyChar == 'x')
break;
else ec.OnKeyHit(cki.KeyChar);
}
}
}
}
(来週)クラスに分割してオーバーライドメソッドでイベント(一桁加算機)
// 何かデリゲートの学習してるみたいだけど、元来のイベント処理手順がわかった。
このようにイベントハンドラはユーザイベントを想定し、条件をトリガーとして、イベント時呼び出されます。
##コールバック
処理呼出(コールバックだから呼戻し?)今までの学習内で5つ程ありました。
Ⅰ.普通にメソッド引数を渡す
処理メソッドに引数定義、①返す用のint w②代入w=x+y
③返す用return w
設定。
Main関数で①返される用のint result
②渡す用のresult=渡したい関数名(引数の値)
③それを用いた処理文
Ⅱ.コンストラクタ
(クラス名と同じにする、Mainにて呼出時インスタンス化、Test test = new Test();)
Ⅲ.オーバーライド
(元メソッドをpublic virtual~
として、派生クラス先はpublic override~
このようにオーバーライドメソッド作る)
(意味は上書き)(条件は引数同じ)
memo.処理内容{return}
にしとけば派生先で元メソッドでも{return}
でそのクラス処理文に対してreturn
で返される。
Ⅳ.デリゲート
①まずクラス外で宣言して 例delegate void DeleName(int a, int b)
②MainでデリゲートをNewインスタンス化か代入 例new DeleName(c.Minus)
③最後に引数代入と共に呼び出し 例d1(2, 1)
Ⅴ.抽象メソッド
(規格みたいな感じ、派生クラス作ってパーツ作れる)①abstract class~、public abstract int~、という風に2回つけて設定
②実装クラスのメソッドにはoverrideつける※基本クラス下の場合
※interface…メソッドではなくクラスと同列階層だが、抽象メンバを呼び出す。当然派生クラス先でパーツ化する。
abstractの利用価値下がる(interfaceだと自由に継承や複数設定ができ汎用性あるclass名: interface1, interface2, ...
)
Ⅵ. ローカル関数 ←New!C#7
メソッドの中に書くメソッド
static void SampleMethod01()
{
// 親メソッドしかアクセス出来ないので修飾子いらない
int LocalFunc01(int a, int b)
=> a + b;
// ここより前で定義されているローカル関数の呼び出し
WriteLine($"LocalFunc01(1,2)={LocalFunc01(1,2)}");
// 出力:LocalFunc01(1,2)=3
※イベントアクセサやプロパティgetter、setterの本体で使える
Before:
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
// After:
public string FullName => FirstName + " " + LastName;
static void SampleMethod03()
{
// ラムダ式でデリゲートを定義して使う従来の書き方
Func<int, bool> IsOdd = (n) =>
{
return n % 2 != 0;
};
var odds = Enumerable.Range(1, 10).Where(IsOdd);
WriteLine($"odds={string.Join(",", odds)}");
// 出力:odds=1,3,5,7,9
// ローカル関数も、通常のメソッドと同様にデリゲートとして扱える
bool IsEven(int n)
{
return n % 2 == 0;
}
var even = Enumerable.Range(1, 10).Where(IsEven);
WriteLine($"evens={string.Join(",", evens)}");
// 出力:evens=2,4,6,8,10
}
ちなみにイベント呼出にはデリゲートとオーバーライドをよく見かけるのですが、
理由があるみたいなので試すのは端折りました。
次回は、オーバーライドで試してイベントプロパティやAction、Funcも確認したいと思います。
memo:発生頻度の低いイベントを数多く定義する場合は、イベントプロパティ