代码合同或if声明?

Wil*_*ler 11 c# if-statement code-contracts

我只是尝试使用代码契约,而且我发现if语句没有真正的优势.

考虑以下.

private static void BindClassesToInterfacesByConvention(string classesEndingWith
    , string interfacesEndingwith) {
    Contract.Requires<ArgumentNullexception>(
        string.IsNullOrWhiteSpace(classesEndingWith)
        , "classesEndingWith");

    Contract.Requires<ArgumentNullException>(
        string.IsNullOrWhitespace(interfacesEndingWith)
        , "interfacesendingWith");

    ...
}
Run Code Online (Sandbox Code Playgroud)

我发现它比简单地使用一个更令人困惑 if statement

private static void BindClassesToInterfacesByConvention(string classesEndingWith
    , string interfacesEndingwith) {
    if (string.IsNullOrWhiteSpace(classesEndingWith)) 
        throw new ArgumentNullException("classesEndingWith");

    if (string.IsNullOrWhitespace(interfacesEndingWith))
        throw new ArgumentNullException("interfacesendingWith");

    ...
}
Run Code Online (Sandbox Code Playgroud)

代码合同应该在编译时警告我合同违反.因此,当我写下以下内容时,我期待得到错误或警告.

BindClassesToInterfacesByConvention(null, null);
Run Code Online (Sandbox Code Playgroud)

没有任何事情发生,一切编译得很好,既没有出现错误也没有出现警告信息.

在这种情况下,我认为最好继续使用it statement.或者也许是不公平的使用Code Contracts

Fra*_*ans 5

代码契约是一个很好的主意,但它的工具并不完全存在。首先,为了实际抛出异常,您必须在 Visual Studio 中安装正确的扩展和/或在您的项目中配置正确的设置。如果您的单元测试依赖于在运行时抛出异常的代码契约并在构建服务器上运行它们,那就太有趣了。

然而,重要的是要理解代码契约的真正目的不仅仅是抛出异常。它启用静态代码分析(如果您打开它),启用后可能会在编译时给您一个错误 - 但它确实需要您做很多工作才能在几乎所有地方应用它以便静态代码分析才能真正起作用。我相信这就是您要测试的场景?在这种情况下,我建议您查看项目的代码合同设置,以确保您已启用所有静态代码检查(这会使您的构建变得相当长)。

此外,重要的是,代码契约允许您将意图传达给方法的调用者;Intellisense 将接受您指定的条件(前提是您安装了正确的扩展)。关于代码契约的信息也可以自动添加到可以伴随程序集的 XML 文件中,这将使您的程序集的第 3 方用户在编写代码时了解您的要求,并允许您包含此信息在用 Sandcastle 等构建的帮助文件中。

这是一个好主意,只是还没有真正在工具中完全实现,所以你偶尔会得到一些有趣的行为。就我个人而言,我几乎暂时停止使用它们。