Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 2010 在VisualStudio2010 Professional中为类库使用代码契约(即无静态检查)有多好?_Visual Studio 2010_C# 4.0_Static Analysis_Code Contracts - Fatal编程技术网

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

Visual studio 2010 在VisualStudio2010 Professional中为类库使用代码契约(即无静态检查)有多好?,visual-studio-2010,c#-4.0,static-analysis,code-contracts,Visual Studio 2010,C# 4.0,Static Analysis,Code Contracts,我创建了一些类库,世界各地的其他人都在使用这些类库,现在我开始使用VisualStudio2010,我想知道,对于我来说,切换到使用代码契约,而不是常规的旧式if语句是多么好的主意 即,与此相反: if (fileName == null) throw new ArgumentNullException("fileName"); 使用以下命令: Contract.Requires(fileName != null); 我问这个问题的原因是我知道静态检查器对我来说是不可用的,所以我对我

我创建了一些类库,世界各地的其他人都在使用这些类库,现在我开始使用VisualStudio2010,我想知道,对于我来说,切换到使用代码契约,而不是常规的旧式if语句是多么好的主意

即,与此相反:

if (fileName == null)
    throw new ArgumentNullException("fileName");
使用以下命令:

Contract.Requires(fileName != null);
我问这个问题的原因是我知道静态检查器对我来说是不可用的,所以我对我所做的一些编译器无法验证的假设有点紧张。这可能会导致下载类库的人在使用静态检查器时无法编译类库。这一点,再加上我甚至不能重现这个问题的事实,使得修复这个问题变得很烦人,而且我想,如果类库看起来甚至没有开箱即用的编译,那么它就无法与我的类库的质量相媲美

所以我有几个问题:

  • 如果您有访问权限,静态检查器是否默认打开?或者在类库中是否有需要打开的设置(因为我没有静态检查器,所以不会打开)
  • 我的恐惧是没有根据的吗?上述情景是一个真正的问题吗
欢迎提供任何建议


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

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

public void LogToFile(string fileName, string message)
{
    Contracts.Requires(fileName != null);
    // log to the file here
}
然后我有了这个代码:

public void Log(string message)
{
    var targetProvider = IoC.Resolve<IFileLogTargetProvider>();
    var fileName = targetProvider.GetTargetFileName();
    LogToFile(fileName, message);
}
公共作废日志(字符串消息)
{
var targetProvider=IoC.Resolve();
var fileName=targetProvider.GetTargetFileName();
日志文件(文件名、消息);
}
现在,IoC开始解析一些“随机”类,它为我提供了一个文件名。假设对于这个库,我不可能得到一个不会给我非空文件名的类,但是,由于IoC调用的性质,静态分析无法验证这一点,因此可能会假设一个可能的值可能为空

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

我知道我可以给代码添加假设,说编译器应该认为我从该方法返回的
文件名
永远不会为空,但是如果我没有静态分析器(VS2010 Professional),上面的代码将为我编译,因此,我可能会把它作为一个沉睡的虫子留给一个有终极目标的人去寻找。换句话说,编译时不会警告这里可能有问题,所以我可能会按原样发布库


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

首先,静态检查器实际上(据我所知)只在终极版/学术版中可用,因此,除非您组织中的每个人都使用它,否则如果他们可能违反不变量,可能不会收到警告

其次,虽然静态分析令人印象深刻,但它不能总是找到可能导致违反不变量的所有路径。然而,这里的好消息是,
Requires
契约在运行时保留——它在IL转换步骤中处理——因此检查在编译时和运行时都存在。这样,它就相当于(但优于)常规的
if()
检查

您可以阅读更多关于代码契约编译执行的运行时重写的信息,还可以阅读

编辑:根据我从手册中收集到的信息,我怀疑您描述的情况确实是可能的。但是,我认为这些将是警告而不是编译错误-您可以使用
System.Diagnostics.codesanalysis.SuppressMessage()
来抑制它们。拥有静态验证器的代码使用者也可以标记要忽略的特定情况,但如果存在大量此类情况,则肯定会带来不便。今天晚些时候,我将尝试找时间对您的场景进行最终测试(我目前无法访问静态验证器)


有一个几乎专门用于代码契约的方法(如果您还没有看到),它可能包含一些您感兴趣的内容。

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

当然,对于实际启用了静态检查器的用户来说,提供一个具有非常恼人的API的库是有变化的,因此我认为,如果您测试了使用静态检查器和不使用静态检查器的API的可用性,则只提供带有合同定义的库是明智的


请注意更改现有的
if(cond)throw ex
调用到
Contracts.Requires(cond)
调用,以调用您在以前版本中已经发布的公共API调用。请注意,
Requires
方法引发的异常(如果我没有记错的话,则为
RequiresViolationException
)与您通常引发的异常不同(为
ArgumentException
)。在这种情况下,使用重载。这样,您的API接口保持不变。

否;静态分析器永远不会阻止编译成功(除非它崩溃!)


静态分析器将警告您未经验证的前置/后置条件,但不会停止编译。

是的,我知道所有这些。我想知道的是,如果分析无法验证参数