2013-12-15 50 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