CodeContracts”;“必需”;理解力

本文关键字:理解力 必需 CodeContracts | 更新日期: 2023-09-27 18:24:40

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

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了吗?

CodeContracts”;“必需”;理解力

我用错Contract.Requires了吗?

是的,你是。Contract.Requires是关于为方法(或属性)声明先决条件。这些条件是必须为true才能继续进行方法调用,否则将违反约定。

让我们看看你的代码:

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 s,并且约定块仅出现在方法的正文顶部

在这里,您似乎试图同时做几件事:

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

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

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

Contract.Ensures(obj != null);

类似地,您的助手方法(Get)可以检查其他合同。