5

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

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以错误的方式使用?

4

2 回答 2

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在合约块之后使用 s,并且合约块出现在方法体的顶部。

于 2013-07-24T16:57:23.890 回答
3

您似乎正在尝试在这里一次做几件事:

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

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

此外,您似乎想保证结果不为空。这样做:

Contract.Ensures(obj != null);

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

于 2013-07-24T16:54:20.590 回答