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

时间:2014-08-29 12:52:56

标签: c# .net visual-studio code-contracts

我正在对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" trust" EnvDTE并忽略这些类型及其属性。

我认为"对外部API保持乐观" CC选项服务于此目的;事实证明它没有。

有没有办法让它按照我想要的方式行事,不需要较低的警告级别

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

3 个答案:

答案 0 :(得分:4)

无法提供详细的解决方案,但这应该可以通过在程序集级别使用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 :)在旁注中,我认为属性是条件的(“CODE_ANALYSIS”)。

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

你有没有尝试过: [assembly: Contracts.ContractVerification(false)]在汇编级别?

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

希望这有帮助,