我可以在代码中留下合同吗;m与非代码合约开发人员使用的代码库合并

本文关键字:代码 开发 合并 合同 我可以 | 更新日期: 2023-09-27 18:20:33

在过去的几个月里,我一直在为公司开发一个辅助项目,但上级现在决定它非常适合现有产品。

我一直在使用微软的代码契约进行静态类型检查来开发辅助项目(部分原因是我以前没有使用过它们,并且很想学习)。

我的问题是,如果我在有Contracts的情况下将代码签入代码库,那么其他开发人员是否都需要安装CodeContracts工具才能继续开发?我知道他们中没有人安装它,而我是这里的大三学生,所以我怀疑我是否能说服他们都接受它。

我使用的是.Net 4.5,因此代码约定库也包括在内,但我想知道Visual Studio是否会在每次进行构建时抱怨它们没有使用构建选项中指定的CONTRACTS_FULL进行构建,或者,如果我将CONTRACTS_FULL保留在构建选项中,当另一个开发人员尝试构建时会发生什么?此外,我想知道当合同失败,但代码还没有用代码合同重写器构建时,最终产品会如何运作。

我只用一个项目就创建了一个新的解决方案。创建了一个简单函数,该函数引发了代码约定冲突,其中卸载了代码约定,并且未指定CONTRACTS_FULL。构建并运行它,收到以下错误:

Run-time exception (line 8): An assembly (probably "hdxticim") must be rewritten using the code contracts binary rewriter (CCRewrite) because it is calling Contract.Requires<TException> and the CONTRACTS_FULL symbol is defined.  Remove any explicit definitions of the CONTRACTS_FULL symbol from your project and rebuild.  CCRewrite can be downloaded from http://go.microsoft.com/fwlink/?LinkID=169180. 
After the rewriter is installed, it can be enabled in Visual Studio from the project's Properties page on the Code Contracts pane.  Ensure that "Perform Runtime Contract Checking" is enabled, which will define CONTRACTS_FULL

我认为错误消息需要重写,因为CONTRACTS_FULL肯定没有指定。

多亏了Matías Fidemraizer,我们发现在使用Contract.Requires<TException>()时会发生这种情况,而不是在Contract.Requires()上。

理想情况下,我想修改这种行为,以便Contract将所提供的异常当作正常的保护语句来触发,而不是抱怨重写器。

下面是一把小提琴来演示这个问题:https://dotnetfiddle.net/cxrAPe

我可以在代码中留下合同吗;m与非代码合约开发人员使用的代码库合并

简短的回答是:是。如果使用代码约定签入代码,那么所有可能生成该代码的开发人员也必须安装代码约定才能生成代码。

与@CBauer在他的回答中所写的相反,代码合同有一个"幸运"的包。不,这不是NuGet包—这是一个基于MSI安装程序的安装。

最后,如果您处于调试构建(例如开发、QA/QC和/或测试)的持续集成环境中,那么这些构建服务器也需要安装代码合同。

使用代码约定时,调试生成始终需要使用代码约定。请注意,版本不一定是情况。这取决于您使用的合同检查形式以及项目属性中指定的选项。

代码合同手册提供了所有详细信息。它很好,我强烈建议花时间阅读和理解它。

需要注意的是,如果使用Contract.Requires<TException>(bool condition)形式的前提条件,则必须Release构建启用代码契约(请参见第5节:使用指南,特别是页面20使用2场景)。

由于您正在将此代码集成到尚未使用代码合同开发的现有代码库中,因此应考虑修改代码合同项目属性设置,以符合代码合同手册第20页所述的使用场景3,并使用"遗留"if-then-throw模式重新制定合同。这将使您的团队能够最好地访问代码库,以便在任何地方使用代码契约,允许您最终用实际的代码契约Contract.Requires(bool condition)检查和Contract.Requires<TException>(bool condition)检查来替换"遗留"。

更新:很快就会有一个用于代码合约的NuGet包我今天在新的GitHub代码合约存储库。对于那些不知道的人来说,微软已经开源了,现在这是一项社区驱动的努力。

他们最近(早在一月份)宣布了v1.10.xxxx.RC1的发布。您可以在他们的GitHub存储库中找到有关它的信息。

不幸的是,如果不强迫同事维护他们的个人环境,很难让一个不是通过nuget安装的库保持最新。代码合约似乎没有微软的官方软件包可供使用

fourpastdirnight的帖子最近更新了我对上面最初关注的问题的回答,但我认为下半部分即使现在仍然相关。得到你们的支持,伙计们!

根据我(公认的主观)的经验,如果没有事先在同事中建立信任,像这样的工具就会遭到谩骂。你可以试着慢慢地讨论这个话题,看看他们是否愿意使用它。如果不安装代码契约重写器,无论是否设置CONTRACTS_FULL

Contract.Requires<TException>()都将失败。

一种解决方案是构建一个单独的类FailableContract,它测试由代码契约设置的预处理器条件CONTRACTS_FULL

然后,您所要做的就是记住,在将代码提交到代码库之前,从构建参数中删除CONTRACTS_FULL。你仍然可以得到代码合约,其他人都可以得到保护声明。

FailableContract的一小部分(我仍在写):

public class FailableContract
{
    public static void Requires(bool condition)
    {
        #if CONTRACTS_FULL
            Contract.Requires(condition);
        #else
            if (!condition) throw new ArgumentException(); //Just go with an argument exception because we haven't been supplied with an exception type.
        #endif
    }
    public static void Requires<TException>(bool condition) where TException : Exception, new()
    {
        #if CONTRACTS_FULL
            Contract.Requires<TException>(condition);
        #else
            if (!condition) throw new TException();
        #endif
    }
}

然后一个简单的Find,Replace Contract. to FailableContract.应该会得到大多数问题。

相关文章: