在我的脑海中,我可以想到4种检查空参数的方法:
Debug.Assert(context != null);
Contract.Assert(context != null);
Contract.Requires(context != null);
if (context == null) throw new ArgumentNullException("context");
我一直使用最后一种方法,但我只是看到了一个使用Contract.Requires
的代码片段,我对它并不熟悉。每种方法的优缺点是什么?还有别的办法吗?
在带有Resharper的VS2010中,
Contract.Assert
警告我这个表达式总是正确的(它怎么知道的,我不太确定...can't HttpContext be null?),Contract.Requires
被淡出,它告诉我编译器不会调用该方法(我假设由于前面的原因,它永远不会为空),context != null
,后面的所有代码都会淡出,并告诉我启发式地无法访问该代码。因此,似乎后3种方法在VS静态检查器中内置了某种智能,而Debug.Assert
就是个哑巴。
发布于 2010-12-15 09:24:30
我的猜测是有一个协定应用于接口IHttpHandler.ProcessRequest,它需要该上下文!= null。接口契约是由其实现者继承的,因此您不需要重复这些要求。实际上,您不允许添加额外的Requires语句,因为您仅限于与接口协定相关联的需求。
我认为在指定合同义务和简单地执行空检查之间进行区分是很重要的。您可以实现null检查并在运行时抛出异常,以此作为通知开发人员正确使用您的API的一种方式。另一方面,约定表达式实际上是元数据的一种形式,它可以由约定重写器解释(以引入以前手动实现的运行时异常),也可以由静态分析器解释,静态分析器可以使用它们来推断应用程序的静态正确性。
也就是说,如果您在一个积极使用Code Contracts和静态分析的环境中工作,那么将断言放在Contract形式中,以利用静态分析肯定是更可取的。即使您没有使用静态分析,您仍然可以通过使用合同为以后的好处敞开大门。需要注意的主要问题是您是否已将项目配置为执行重写,否则契约将不会像您预期的那样导致运行时异常。
为了详细说明评论者所说的话,Assert、Assume和Requires之间的区别是:
发布于 2010-12-15 09:24:38
第一种方法适用于测试不应该存在的null条件。也就是说,在开发过程中使用它,以确保它不会意外地设置为null。因为它不做任何错误处理,所以它不适合处理您发布的产品中的null条件。
我想说的是,第二版和第三版是相似的,因为它们没有以任何方式处理这个问题。
通常,如果变量在最终产品中实际上可能为空,则使用最后一个版本。您可以在那里进行特殊处理,或者像您所做的那样引发异常。
https://stackoverflow.com/questions/4445898
复制相似问题