C# 如何使代码契约忽略特定的程序集引用?

C# 如何使代码契约忽略特定的程序集引用?,c#,.net,visual-studio,code-contracts,C#,.net,Visual Studio,Code Contracts,我正在对VisualStudio进行扩展。在代码中,我使用代码契约进行断言和检查。我将警告选项级别设置为高 我想做的是保持警告级别,同时忽略对EnvDTE引用所做的任何检查 考虑以下代码示例: public static string GetAbsoluteOutputFolder(EnvDTE.Project project) { if (project == null) throw new ArgumentNullException("project"); var path

我正在对VisualStudio进行扩展。在代码中,我使用代码契约进行断言和检查。我将警告选项级别设置为高

我想做的是保持警告级别,同时忽略对EnvDTE引用所做的任何检查

考虑以下代码示例:

public static string GetAbsoluteOutputFolder(EnvDTE.Project project)
{
    if (project == null) throw new ArgumentNullException("project");

    var path =
        project.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath").Value.ToString();
    //...
}
在我的当前设置下,CC要求我在分配
path
变量之前添加以下检查:

Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);
因此,我想在这里告诉CC“信任”EnvDTE并忽略这些类型及其属性

我认为“对外部API持乐观态度”CC选项就是为了达到这个目的;事实证明不是这样

有没有一种方法可以让它按照我想要的方式运行,而不需要更低的警告级别


编辑:我想要一个能够在项目级别工作并且仍然允许执行“定期”检查的解决方案。

无法提供详细的解决方案,但这应该可以通过使用基线功能或System.Diagnostics.CodeAnalysis.SuppressMessage在程序集级别解决:

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Contracts", "Whatever")]
可以使用SuppressMessageAttribute的“Target”属性仅忽略特定类型/方法/命名空间上的消息:

[SuppressMessage("Microsoft.Contracts", 
                 "CC1055", 
                 Scope="Member", 
                 Target="YouNamespace.EnvDTE.Project")]
请注意,我使用的参数只是一个很好的选择,您必须自己找出正确的作用域、MessageId和Target:)在旁注上,我认为属性是有条件的(“代码分析”)


对于这个问题,官方建议的解决方案是创建某种包装器,在您的情况下,可能是创建或包含EnvDTE.Project对象的存储库。然后,您可以添加所需的合同。确保有。

您是否尝试过以下内容:
[组装:合同。合同验证(false)]
在组装级别

您应该能够动态执行此操作:


希望这会有所帮助,

我认为解决这个问题是不可能的,但由于C#6.0,有一种解决方法,至少可以减轻一点痛苦:

而不是

Contract.Assume(project.ConfigurationManager != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration != null);
Contract.Assume(project.ConfigurationManager.ActiveConfiguration.Properties != null);
你现在可以写了

Contract.Assume(project.ConfigurationManager?.ActiveConfiguration?.Properties != null);

如果是我,我会加上你想省略的支票。如果您的代码因为EnvDTE中某个地方的空引用而崩溃。进行这些检查的Project应该让您确切地知道问题所在,而不是试图猜测空引用的位置。@MikeBurdick问题是,其中一些属性很可能永远不会为空。但是,由于该程序集没有使用合同进行编译,因此引擎无法判断。因此,它像对待任何没有合同的财产一样对待这些财产,迫使对同一财产反复使用无意义的检查。如果有一个全局的,一次执行一次的方法来强制执行
配置。属性
(例如)永远不会返回null。我很乐意使用它,但是没有。因此,我认为较小的错误是告诉CC忽略属于该特定程序集的任何代码。如果我不拥有该程序集的代码,如何放置程序集级别的警告?@Crono:您可以使用SuppressMessageAttribute的“Target”属性来抑制外部LIB上的消息,我将把它添加到答案中。如果我正确理解这个属性,它只会阻止该程序集中的契约验证。OP希望忽略使用程序集创建的所有警告。