1

スイッチのすべてのケースをプログラムで取得することは可能ですか? おそらくILによるものですが、どうすればよいかわかりません...

実際、私のグローバルな問題は次のとおりです。プロパティ名として文字列を使用した siwtch ケースを取得しました。この方法は非常に重要であり、回帰は許されません。これを壊すリファクタリングはしたくないので、すべてのケース文字列が実際にオブジェクトの実際のプロパティであることをテストするメソッドが必要です。(NB : デフォルト値は何かを返すため、リファクタリングされた無効な値に対して exception をスローすることはできません)。

4

4 に答える 4

2

コード内でプロパティ名を文字列として直接使用しないようにする方法があります。ここにコード スニペットを投稿しました。

次に、switch ステートメントを使用する代わりに、次のようなものを実装します。

private IDictionary<string, Action> _actions;

public void RegisterAction(string propertyName, Action action)
{
    _actions.Add(propertyName, action);
}

public void DoSomething(string propertyName)
{
    _actions[propertyName]();
}

両方のメソッドを呼び出すときは、プロパティ名を直接使用するのではなく、コード スニペット (リンクを参照) の Member クラスを使用してください。したがって、「魔法の文字列」が含まれていないため、コードがリファクタリング防止であることを確認できます。

よろしくお願いします

于 2009-09-01T08:28:21.110 に答える
2

IL では、switch ステートメントは次のようにコンパイルされます。

// ...
L_000c: ldloc.1 
L_000d: ldstr "case1"
L_0012: call bool [mscorlib]System.String::op_Equality(string, string)
L_0017: brtrue.s L_0035
L_0019: ldloc.1 
L_001a: ldstr "case2"
L_001f: call bool [mscorlib]System.String::op_Equality(string, string)
L_0024: brtrue.s L_0042
L_0026: ldloc.1 
L_0027: ldstr "case3"
L_002c: call bool [mscorlib]System.String::op_Equality(string, string)
L_0031: brtrue.s L_004f
// ...

すべてのケースでこれを適切に分析できるコードを作成するには、かなりの作業が必要です。

これをテストする唯一の方法は、実際にすべてのケースをカバーし、PropertyInfo が null にならないようにすることです。作業しているコードが非常に重要で失敗できない場合、いずれにせよリフレクションを使用するのはおそらくかなり危険です。より型安全な設計に移行できますか?

于 2009-09-01T08:36:28.160 に答える
1

スイッチで値を取得するのは簡単ではありません...

スイッチで文字列の代わりに列挙型を使用すると、 を使用して列挙型の値を簡単に取得できますEnum.GetValues

于 2009-09-01T08:23:04.910 に答える
0

ソース自体をチェックするスクリプトを AWK や Perl などで作成し、すべてのビルドの前に実行します。

于 2009-09-01T08:52:03.603 に答える