代码合同"必须"理解

5
我尝试了以下代码来启用某种非空检查以确保在执行具体业务之前,检索到的实体是存在的:
protected T GetRequired<T>(object id)
    where T : EntityObject
{
    var obj = Get<T>(id);
    Contract.Requires<ArgumentNullException>(obj != null);
    return obj;
}

但是在编译时,我遇到了以下问题:
在协定块之后,发现使用在协定块中定义的本地变量“obj”

我是否错误地使用了Contract.Requires

2个回答

6

我是否错误地使用了Contract.Requires

是的,您错了。 Contract.Requires用于声明方法(或属性)的前提条件。这些条件必须为方法调用为真,否则您将违反合同。

让我们看看您的代码:

var obj = Get<T>(id);
Contract.Requires<ArgumentNullException>(obj != null);

在这里,您正在尝试在方法完成执行后(在此情况下为Get方法)使用它来确保某些内容是正确的。这将是一个后置条件,您可以在Get方法的主体中使用Contract.Ensures来实现:

protected T Get<T>(object id) {
    Contract.Ensures(Contract.Results<T>() != null);
    // get and return result
}

最后,这个编译错误

在合约块之后,发现使用在合约块中定义的本地变量obj

这条消息是由于你不能在合约块后面使用Contract。而且合约块只能出现在方法主体的顶部。


3

看起来你正在尝试同时做几件事情:

Contract.Requires 应该直接用在输入参数上,例如,如果 id 不应该为空,那么应该这样写:

Contract.Requires<ArgumentNullException>(id != null);

此外,您似乎希望确保结果不为空。请按照以下方式执行:
Contract.Ensures(obj != null);

同样地,你可以通过你的辅助方法(Get)检查额外的合同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接