2009-09-01 94 views
1

是否有可能通過編程方式檢索交換機的所有情況?我沒有任何想法,也許由IL,但不知道該怎麼辦...C#迭代交換機的情況

事實上,我的全球性問題如下:我得到了一個siwtch與字符串作爲屬性名稱的情況。該方法非常重要,並且不允許迴歸。我不希望重構破壞這個,所以我想要一個方法來測試所有的大小寫字符串事實上是我的對象的屬性。 (注意:默認值返回一些東西,所以我不能爲一個重構的無效值拋出exceptino)。

+0

只是好奇:你打算運行這個檢查作爲你的構建過程的一部分? –

+0

不,我想將它添加到類的靜態構造函數或明確調用它,但我可以想象在構建過程中執行它。 – Toto

回答

2

有一些方法可以避免在代碼中直接使用屬性名稱作爲字符串。我已經發布了一個代碼片段here

然後,而不是使用switch語句,實現這樣的事情:

private IDictionary<string, Action> _actions; 

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

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

當你調用這兩種方法,確保您使用會員類的代碼片段(見鏈接),而不是使用該屬性名稱直接。因此,您可以確保您的代碼不具有重構功能,因爲它不包含任何「魔術字符串」。

問候

+0

最後,按照建議使用鏈接帖子和詞典中顯示的代碼,thx! – Toto

1

獲取交換機中的值不會是微不足道的......

如果在交換機而不是字符串使用一個枚舉,你可以很容易地使用Enum.GetValues枚舉值。

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 
// ... 

這將是一個相當數量的工作編寫的代碼,可以在任何情況下正確地分析這一點。

我可以看到測試這個的唯一方法是實際覆蓋所有情況並確保您不會以null PropertyInfo結束。如果您使用的代碼非常重要且無法失敗,那麼在任何情況下使用反射都可能非常危險。你能轉向更安全的設計嗎?

+0

如果開關變大,C#編譯器將生成一個散列表作爲開關實現......不是非常友好的IL :) –

+0

相反,如果開關不小,那麼獲得散列表是小菜一碟 - 請參閱下面的答案。 –

+0

當然,我並不認爲這很容易做到。事實上,代碼可以拋出異常,我只是不希望它與一個無效的字符串作爲屬性確定。 – Toto

0

用AWK或Perl編寫腳本,或者其他來檢查源代碼本身,並在每次構建之前運行它。

相關問題