2013-12-15 92 views
3

在編寫一些代碼來模擬System.Array的儘可能完整的仿真時,我遇到了一些令我感到困惑和危險的東西。ReliabilityContract和IComparer(或其他注入代碼)

以下方法簽名:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] 
public static int BinarySearch<T>(T[] array, T value, IComparer<T> comparer) 

的方法都被定義合同說,它絕對不會損壞任何狀態下,即使本身,如果有故障。這也意味着合同外部的一些代碼將通過comparer值調用,而IComparer<T>.Compare不需要可靠性合同;致電comparer.Compare(x,y)的電話肯定會腐化國家並違反合同。

這是如何有效?我不是使用約束執行的專家......受約束的執行環境是否會在運行時檢查Compare方法,並且如果預計合同被強制執行,會導致異常?這是可靠性合同中的一個漏洞嗎?

或者,我在非框架代碼中應該避免的約束執行區CIL voodoo?我想盡可能保持原生System.Array的行爲,所以我想在底層實現支持它的地方保持相同的屬性;但在我看來,即使內部也無法保證合同,所以我很疑惑如何能保證合同。

+0

無論如何,你不會非常接近原生System.Array的行爲。數組是運行時魔術 - 泛型實現之前的泛型,魔術重定向,假裝數組是通用類實現之後的通用類型...數組自身是伏都教:P – Luaan

回答

3

AFAIK,CER s是一個非常先進的功能,很少使用。除非你真的希望你的課程能夠在CER中使用(或者如果你不確定CER是真實的),你不應該指定任何ReliabilityContract

如果您仍然想要調查CER,請閱讀Stephen Toub的Keep Your Code Running with the Reliability Features of the .NET Framework。我認爲這篇文章中最相關的部分是(重點是我的):

可靠性合同也有一些有趣的解釋問題。例如,CLR設計人員遇到的一個問題是,大多數實施良好的方法會檢查其參數,併爲無效的輸入引發異常。因此,簡單地取消核證減排量內所有分配的方法幾乎是無用的(某些方法也可能分配,然後從任何內存不足例外中恢復)。可靠性契約是試圖從運行時抽象出這種類型的細節,允許代碼作者清楚地說明調用者是否需要擔心失敗,如果是,需要拋棄多少狀態。因此,如果傳遞給方法的參數是非法的或方法使用不正確,那麼可靠性合同被認爲是無效的。此外,可能存在不容易通過合同表達的概念。設想一種接受Object作爲參數並調用其Equals方法的方法。 此方法可能是可靠的,但前提是您傳遞的對象具有可靠的等於重寫。目前沒有內建的方式來表達這個概念。

認爲高亮顯示的部分意味着BinarySearch不應該被標記爲WillNotCorruptState。或者,與委託相關的案例可能比調用通過object更加透明,所以這裏的屬性實際上是可以的。

無論如何,我認爲爲了安全起見,除非您真的知道自己在做什麼,而且確實需要它,否則不應指定任何ReliabilityContract