代码契约与通用扩展方法中的if

时间:2013-06-26 08:07:28

标签: c# if-statement code-contracts throw

在我当前的系统中,我决定构建一些通用的Extension方法,以便稍后在整个当前系统中重用。

当我使用 Microsoft Code Contracts 时,我首先决定将其包含在内,以验证sourcerange

1)

public static class MyExtensions {
    public static void RemoveRange<T>(this ObservableCollection<T> source, IEnumerable<T> range) where T : class {
        Contract.Requires(source != null);
        Contract.Requires(range != null);

        foreach (var element in range) {
            source.Remove(element);
        }
    }       
}

另一种实现方式是一种经典的方式:

2)

public static class MyExtensions {
    public static void RemoveRange<T>(this ObservableCollection<T> source, IEnumerable<T> range) where T : class {
        if (source == null) {
            throw new ArgumentNullException("source");
        }

        foreach (var element in range) {
            source.Remove(element);
        }
    }   
}

在此之前,我没有以可在其他系统中重复使用的方式设计通用类的要求

编辑(开始) (通过另一个系统我的意思是具有不同体系结构的不同系统。示例:当前系统如果用于金融部门,它使用代码合同。但是其他系统可以用于军事部门,不会使用用于验证的代码合同。) 编辑(结束)

我与我的同事讨论了如何在另一个系统中使用Extension方法重用该Generic类?

I)意见是保持代码合同,因为这是整个当前系统中的验证规则。 (如第一个例子)。

这种方式的优势是我在整个系统中保留一种验证方式(仅通过代码合同)。 缺点是这个带有扩展方法的测试通用类在其他系统中不可重用(可能不会使用代码合同进行验证)而不用经典If/Throw Exception替换合同。

II)另一种观点是设计具有Extension方法的Generic类在其他系统中可重用,即使我们直到现在还没有这样的要求。此意见需要经典的验证实现,通过 IF 抛出异常(如第二个示例中所示)。

这种方式的优点是带有扩展方法的经过测试的通用类可以重复使用而无需更改。但 disadvange 是接近另一种类型的验证。

欢迎任何有关使用哪种方法的建议/意见。

感谢您的关注!

1 个答案:

答案 0 :(得分:1)

您可以将代码约定添加到类库,而不会对使用该类库的任何其他程序集引入代码约定的依赖。

代码契约由重写器实现,该重写器更改指定代码契约的代码。其余的代码合同支持已经在.Net 4或更高版本中提供,因此其他代码可以愉快地引用使用代码合同的库,而无需采取任何特殊步骤。

因此,您可以在某些程序集中使用代码约定,而不必担心引用这些程序集的任何其他内容。

具体而言,这种说法不正确:

  

缺点是这个带有扩展方法的测试通用类不能在另一个系统中重复使用(可能不会使用代码合同进行验证)而不用经典的If / Throw异常替换Contracts。

因为可以在“其他系统”中重复使用它(如果“其他系统”是指“不使用代码合同的程序集”)。