CodeContracts“必需”理解

时间:2013-07-24 16:48:51

标签: c# .net code-contracts

我尝试了以下代码,以便在执行某些具体业务之前为检索到的实体启用某种非空检查以确保它们存在:

protected T GetRequired<T>(object id)
    where T : EntityObject
{
    var obj = Get<T>(id);
    Contract.Requires<ArgumentNullException>(obj != null);
    return obj;
}

但是在编译时我得到了:
After contract block, found use of local variable 'obj' defined in contract block

我是否以错误的方式使用Contract.Requires

2 个答案:

答案 0 :(得分:6)

  

我是否以错误的方式使用Contract.Requires

是的,你是。 Contract.Requires是关于为方法(或属性)声明前置条件。这些条件必须才能使方法调用继续进行,否则您将违反合同。

让我们来看看你的代码:

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

在这里,尝试使用它来确保在方法执行完毕后某些事情是真的(在这种情况下,Get方法) 。这将是后置条件,为此您可以在Contract.Ensures的正文中使用Get

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

最后,这个编译错误

  

在合同阻止之后,发现使用了合同块中定义的局部变量obj

此消息是因为您无法在合同阻止后使用Contract,并且合约区块仅显示在方法的主体顶部。 / p>

答案 1 :(得分:3)

似乎你在这里尝试做几件事情:

Contract.Requires应直接用于输入参数,例如如果id永远不应为null,那么请这样做:

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

此外,您似乎希望保证结果不为null。这样做:

Contract.Ensures(obj != null);

同样,您的帮助方法(Get)可以检查其他合同。