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

本文关键字:程序集 引用 何使 代码 约定 | 更新日期: 2023-09-27 18:20:08

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

我想做的是保持该警告级别,同时忽略对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选项正是出于这个目的;事实证明不是。

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

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

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

无法提供详细的解决方案,但应通过在程序集级别使用Baseline Feature或System.Diagnostics.CodeAnalysis.SuppressMessage来解决此问题:

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Contracts", "Whatever")]

您可以使用SuppressMessageAttribute的"Target"属性来仅忽略特定类型/方法/命名空间上的消息:

[SuppressMessage("Microsoft.Contracts", 
                 "CC1055", 
                 Scope="Member", 
                 Target="YouNamespace.EnvDTE.Project")]

注意,我使用的参数只是一个很好的选择,你必须自己计算出正确的Scope、MessageId和Target:)顺便说一句,我认为Attribute是Conditional("CODE_ANALYSIS")。

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

我认为不可能解决这个问题,但由于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);

您尝试过以下功能吗:组装级别的[assembly: Contracts.ContractVerification(false)]

您应该能够动态地执行此操作:https://msdn.microsoft.com/en-us/library/bb458043.aspx

希望这有帮助,