回答編集履歴
6
プログラム修正
answer
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
cache = typeof(クラス名)
|
11
11
|
.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
|
12
12
|
.Where(mi => mi.ReturnType == typeof(Void))
|
13
|
-
.Where(mi => mi.GetParameters().SingleOrDefault()?.ParameterType
|
13
|
+
.Where(mi => mi.GetParameters().SingleOrDefault()?.ParameterType == typeof(string[]))
|
14
14
|
.ToDictionary(
|
15
15
|
mi => mi.Name,
|
16
16
|
mi => mi.CreateDelegate(typeof(Action<string[]>), null) as Action<string[]>);
|
5
不備があったので修正
answer
CHANGED
@@ -9,6 +9,7 @@
|
|
9
9
|
{
|
10
10
|
cache = typeof(クラス名)
|
11
11
|
.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
|
12
|
+
.Where(mi => mi.ReturnType == typeof(Void))
|
12
13
|
.Where(mi => mi.GetParameters().SingleOrDefault()?.ParameterType() == typeof(string[]))
|
13
14
|
.ToDictionary(
|
14
15
|
mi => mi.Name,
|
@@ -32,15 +33,17 @@
|
|
32
33
|
|
33
34
|
上のコードではリフレクションを使い、
|
34
35
|
まず static かつ public では無いメソッドを片っ端から取得します。
|
35
|
-
さらに、引数が一つでその型が string[] という情報を元にコマンドだけを絞り込んでいきます。
|
36
|
+
さらに、戻り値無し、引数が一つでその型が string[] という情報を元にコマンドだけを絞り込んでいきます。
|
36
37
|
|
37
38
|
また、この処理中に何度か配列が返ってくるのですが、これをスマートに処理する Linq という機能を使っています。
|
38
39
|
Where, SingleOrDefault, ToDictionary が Linq です。
|
39
40
|
|
40
41
|
=> の部分はラムダ式といって、デリゲート(後述)を簡単に定義する記法です。
|
41
42
|
|
42
|
-
リフレクションは負荷のかかる処理なので、デリゲート(関数ポインタのようなもの
|
43
|
+
リフレクションは負荷のかかる処理なので、デリゲート(関数ポインタのようなもの)に変換して負荷を軽くします。
|
43
44
|
これによって、各コマンドのデリゲート(関数ポインタ)が作成されます。
|
45
|
+
こんな感じです。
|
46
|
+
delegate void Action<string[]>(string[]);
|
44
47
|
|
45
48
|
switch文の処理はまるまる Dictionary.TryGetValue() で置き換えました。
|
46
49
|
|
4
変な日本語を修正
answer
CHANGED
@@ -32,7 +32,7 @@
|
|
32
32
|
|
33
33
|
上のコードではリフレクションを使い、
|
34
34
|
まず static かつ public では無いメソッドを片っ端から取得します。
|
35
|
-
さらに、引数が一つでその型が string[] という情報を元に
|
35
|
+
さらに、引数が一つでその型が string[] という情報を元にコマンドだけを絞り込んでいきます。
|
36
36
|
|
37
37
|
また、この処理中に何度か配列が返ってくるのですが、これをスマートに処理する Linq という機能を使っています。
|
38
38
|
Where, SingleOrDefault, ToDictionary が Linq です。
|
3
変な日本語を修正
answer
CHANGED
@@ -28,11 +28,11 @@
|
|
28
28
|
|
29
29
|
何やってるかわからないと思うので、解説を追記します。
|
30
30
|
|
31
|
-
.NET にはリフレクションという機能があり、プログラム実行時にプロパティやメソッドを検索
|
31
|
+
.NET にはリフレクションという機能があり、プログラム実行時にプロパティやメソッドを検索できます。
|
32
32
|
|
33
|
-
上のコードでは
|
33
|
+
上のコードではリフレクションを使い、
|
34
|
-
static かつ public では無いメソッドを片っ端から取得し
|
34
|
+
まず static かつ public では無いメソッドを片っ端から取得します。
|
35
|
-
引数が一つでその型が string[] という情報を元にメソッドだけを絞り込んでいきます。
|
35
|
+
さらに、引数が一つでその型が string[] という情報を元にメソッドだけを絞り込んでいきます。
|
36
36
|
|
37
37
|
また、この処理中に何度か配列が返ってくるのですが、これをスマートに処理する Linq という機能を使っています。
|
38
38
|
Where, SingleOrDefault, ToDictionary が Linq です。
|
2
解説を追記
answer
CHANGED
@@ -15,11 +15,33 @@
|
|
15
15
|
mi => mi.CreateDelegate(typeof(Action<string[]>), null) as Action<string[]>);
|
16
16
|
}
|
17
17
|
|
18
|
-
public void InvokeCommand(string name, string[] args)
|
18
|
+
public static void InvokeCommand(string name, string[] args)
|
19
19
|
{
|
20
20
|
if (cache.TryGetValue(name, out var cmd))
|
21
21
|
{
|
22
22
|
cmd(args);
|
23
23
|
}
|
24
24
|
}
|
25
|
-
```
|
25
|
+
```
|
26
|
+
|
27
|
+
---
|
28
|
+
|
29
|
+
何やってるかわからないと思うので、解説を追記します。
|
30
|
+
|
31
|
+
.NET にはリフレクションという機能があり、プログラム実行時にプロパティやメソッドを検索する機能があります。
|
32
|
+
|
33
|
+
上のコードでは
|
34
|
+
static かつ public では無いメソッドを片っ端から取得し、
|
35
|
+
引数が一つでその型が string[] という情報を元にメソッドだけを絞り込んでいきます。
|
36
|
+
|
37
|
+
また、この処理中に何度か配列が返ってくるのですが、これをスマートに処理する Linq という機能を使っています。
|
38
|
+
Where, SingleOrDefault, ToDictionary が Linq です。
|
39
|
+
|
40
|
+
=> の部分はラムダ式といって、デリゲート(後述)を簡単に定義する記法です。
|
41
|
+
|
42
|
+
リフレクションは負荷のかかる処理なので、デリゲート(関数ポインタのようなもの ここでは Action<> )に変換して負荷を軽くします。
|
43
|
+
これによって、各コマンドのデリゲート(関数ポインタ)が作成されます。
|
44
|
+
|
45
|
+
switch文の処理はまるまる Dictionary.TryGetValue() で置き換えました。
|
46
|
+
|
47
|
+
難しいとは思いますが、 C# のエッセンスが詰まっているのでぜひ勉強してみてください。
|
1
誤字修正
answer
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
{
|
10
10
|
cache = typeof(クラス名)
|
11
11
|
.GetMethods(BindingFlags.Static | BindingFlags.NonPublic)
|
12
|
-
.Where(mi => mi.GetParameters().
|
12
|
+
.Where(mi => mi.GetParameters().SingleOrDefault()?.ParameterType() == typeof(string[]))
|
13
13
|
.ToDictionary(
|
14
14
|
mi => mi.Name,
|
15
15
|
mi => mi.CreateDelegate(typeof(Action<string[]>), null) as Action<string[]>);
|