C# 通用扩展方法中的代码契约与if
在我当前的系统中,我决定构建一些通用的扩展方法,以便以后在整个当前系统中重用 由于我使用的是Microsoft代码契约,我决定首先将它们包括进来,以验证C# 通用扩展方法中的代码契约与if,c#,if-statement,code-contracts,throw,C#,If Statement,Code Contracts,Throw,在我当前的系统中,我决定构建一些通用的扩展方法,以便以后在整个当前系统中重用 由于我使用的是Microsoft代码契约,我决定首先将它们包括进来,以验证源代码和范围 1) 公共静态类MyExtensions{ 公共静态void RemoveRange(此ObservableCollection源,IEnumerable范围),其中T:class{ Contract.Requires(source!=null); Contract.Requires(范围!=null); foreach(范围内的v
源代码
和范围
1)
公共静态类MyExtensions{
公共静态void RemoveRange(此ObservableCollection源,IEnumerable范围),其中T:class{
Contract.Requires(source!=null);
Contract.Requires(范围!=null);
foreach(范围内的var元素){
来源。删除(元素);
}
}
}
另一种实现方式是一种经典方式:
2)
公共静态类MyExtensions{
公共静态void RemoveRange(此ObservableCollection源,IEnumerable范围),其中T:class{
if(source==null){
抛出新的ArgumentNullException(“源”);
}
foreach(范围内的var元素){
来源。删除(元素);
}
}
}
直到现在,我还没有这样的需求来设计泛型类,使其能够在其他系统中重用
编辑(开始)
(我所说的另一个系统是指具体不同的系统,具有不同的体系结构。例如:当前的系统如果用于金融部门,则使用代码合同。但其他系统可以用于军事部门,不会使用代码合同进行验证。)
编辑(结束)
我与同事讨论了该泛型类在另一个系统中的可重用性和扩展方法
I)一个观点是保留代码契约,因为在整个当前系统中,这是一个验证规则。(如第一个示例中所示)
这种方法的优点是我在整个系统中保留了一种验证方法(仅通过代码契约)。的缺点是,如果不将契约替换为经典的If/Throw Exception
,那么这个带有扩展方法的测试泛型类将无法在其他系统中重用(可能不会使用代码契约进行验证)
II)另一种观点是,使用扩展方法设计泛型类,以便在其他系统中可重用,即使我们到目前为止还没有这样的需求。该意见要求通过IF和抛出异常(如第二个示例)进行经典的验证实现
这种方法的优点是使用扩展方法测试的泛型类可以在不做任何更改的情况下重用。但是的缺点是另一种类型的验证正在进行中
欢迎就使用哪种方法提出任何建议/建议
谢谢你的提醒 您可以将代码约定添加到类库中,而无需为使用该类库的任何其他程序集引入对代码约定的依赖关系 代码契约由重写器实现,重写器更改指定代码契约的代码。代码契约支持的其余部分已经嵌入到.NET4或更高版本中,因此其他代码可以愉快地引用使用代码契约的库,而无需采取任何特殊步骤 因此,您可以在某些程序集中使用代码约定,而不必担心引用这些程序集的任何其他内容 具体来说,这种说法是不正确的: 缺点是,如果不将契约替换为经典的If/Throw异常,这个带有扩展方法的测试泛型类将无法在其他系统中重用(可能不会使用代码契约进行验证)
因为您可以在“其他系统”中重用它(如果您所说的“其他系统”是指“不使用代码契约的程序集”)。因此,在一句话中,您要求的代码契约应该是泛型库的依赖项?@Mehrdad,不是!我不要这个,谢谢。我所说的“其他系统”是指具体不同的系统,具有不同的体系结构。示例:当前系统适用于金融部门,并使用代码合同。但另一个系统可以用于军事部门,它不会使用代码契约进行验证。@meorfi,这并不意味着你不能使用代码契约——因为这只是用来验证程序参数之类的东西,而且这两种方法都会抛出异常,你应该能够互换使用它们,至少用于验证方法参数。你是说代码契约是一种最佳实践,应该在任何类型的系统中使用吗?@meorfi不一定,但我的意思是,在一个系统中使用它们不会对不使用它们的系统产生负面影响。如果有人因为每次重建(或其他动机)都需要很长时间而决定不使用代码契约,会发生什么。。。
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);
}
}
}
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);
}
}
}