在类库中使用Visual Studio 2010 Professional中的代码契约(即无静态检查)有多好?

ang*_*son 8 static-analysis visual-studio-2010 code-contracts c#-4.0

我创建了类库,其中一些是世界各地的其他人使用的,现在我开始使用Visual Studio 2010,我想知道切换到使用代码契约是多么好的想法,而不是常规的旧代码 - 风格if语句.

即.而不是这个:

if (fileName == null)
    throw new ArgumentNullException("fileName");
Run Code Online (Sandbox Code Playgroud)

用这个:

Contract.Requires(fileName != null);
Run Code Online (Sandbox Code Playgroud)

我问的原因是我知道静态检查器不可用,所以我对我做的一些假设有点紧张,编译器无法验证.当有静态检查程序时,这可能导致类库无法为下载它的人编译.这个,再加上我甚至无法重现这个问题的事实,会让它很难解决,而且我会认为它不会说我的类库的质量如果它看起来甚至没有编译出来的框.

所以我有几个问题:

  • 如果您有权访问静态检查器,则默认情况下是否打开?或者我需要在类库中打开一个设置(因为我没有静态检查器,我不会)
  • 我的恐惧是否毫无根据?以上情况是否真的存在问题?

任何的建议都受欢迎.


编辑:让我澄清一下我的意思.

假设我在类中有以下方法:

public void LogToFile(string fileName, string message)
{
    Contracts.Requires(fileName != null);
    // log to the file here
}
Run Code Online (Sandbox Code Playgroud)

然后我有这个代码:

public void Log(string message)
{
    var targetProvider = IoC.Resolve<IFileLogTargetProvider>();
    var fileName = targetProvider.GetTargetFileName();
    LogToFile(fileName, message);
}
Run Code Online (Sandbox Code Playgroud)

现在,在这里,IoC启动,解决了一些"随机"类,它为我提供了一个文件名.让我们说对于这个库,没有办法可以找回一个不会给我一个非空文件名的类,但是,由于IoC调用的性质,静态分析无法验证这个,因此可能假设一个可能的值可能为null.

因此,静态分析可能会得出结论,存在LogToFile使用null参数调用方法的风险,因此无法构建.

我理解我可以在代码中添加假设,说编译器应该认为fileName我从该方法返回的那个永远不会为null,但是如果我没有静态分析器(VS2010 Professional),那么代码会为我编译,因此我可能会将此作为一个睡眠错误,让终极找到的人.换句话说,这里可能没有编译时警告可能存在问题,因此我可能会按原样释放库.

这是一个真实的场景和问题吗?

Ste*_*ven 2

当您的LogToFile和方法都是库的一部分时,一旦您打开静态检查器,Log您的方法可能无法编译。Log当您向使用静态检查器编译您的代码的其他人提供代码时,当然也会发生这种情况。但是,据我所知,您客户的静态检查器不会验证您所发送的程序集的内部结构。它将根据程序集的公共 API 静态检查自己的代码。所以只要你只发送 DLL,就可以了。

当然,对于实际启用了静态检查器的用户来说,发布一个具有非常烦人的 API 的库是有变化的,所以我认为如果您测试了 API 的可用性,建议仅发布包含契约定义的库有或没有静态检查器。

请注意,有关将现有if (cond) throw ex调用更改为Contracts.Requires(cond)您已在先前版本中提供的公共 API 调用的调用。请注意,该Requires方法抛出的异常(RequiresViolationException如果我没记错的话,是 a )与通常抛出的异常 (a ) 不同ArgumentException。在这种情况下,请使用Contract.Requires重载。这样你的API接口就保持不变。