如何在 FxCop 的自定义规则中获取传递给方法的参数值?

Posted

技术标签:

【中文标题】如何在 FxCop 的自定义规则中获取传递给方法的参数值?【英文标题】:How can I get the value of a parameter passed to a method in a custom rule in FxCop? 【发布时间】:2010-08-16 07:30:09 【问题描述】:

由于某些原因,在我们的 ASP.NET Web 应用程序中,不建议使用Response.Redirect("something", True)。对于 endResponse 参数,它应该与 False 一起使用。我们希望通过自定义 FxCop 规则来强制执行此操作。 我设法找到了 Response.Redirect 的用法,但现在我想找到 endResponse 参数的值。我该怎么做?

我们正在使用以下代码:

public override ProblemCollection Check(Member member)

    var method = member as Method;
    if (method != null)
    
        foreach (var instruction in method.Instructions)
        
            switch (instruction.OpCode)
            
                case OpCode.Call:
                case OpCode.Callvirt:
                case OpCode.Newobj:
                    var call = (Method) instruction.Value;
                    if (call == null)
                    
                        break;
                    
                    if (call.Name.Name != "Redirect")
                    
                        break;
                    
                    if (call.Parameters.Count == 1)
                    
                        //Redirect(url)
                        var resolution = GetResolution();
                        var problem = new Problem(resolution);
                        Problems.Add(problem);
                    
                    if (call.Parameters.Count == 2)
                    
                        VisitStatements(call.Body.Statements);
                    
                    break;
                default:
                    break;
            
        
    

    return Problems;


public override void VisitExpression(Expression expression)

    var methodCall = expression as MethodCall;
    if (methodCall == null)
    
        return;
    

    foreach (var operand in methodCall.Operands)
    
        if (operand.Type.Name.Name == "Int16" || operand.Type.Name.Name == "Int32" || operand.Type.Name.Name == "Int64")
        
            var literal = operand as Literal;
            if (literal != null && literal.Value is int)
            
                var literalValue = (int)literal.Value;
                if (literalValue == 1)
                
                    var resolution = GetResolution();
                    var problem = new Problem(resolution);
                    Problems.Add(problem);
                
            
        
    

我使用过Introspector 并认为endResponse 参数是幕后的整数,但我不再那么确定了。无论如何,methodCall.Operands 中似乎没有任何布尔值。

有没有人遇到过类似的情况,需要检查传递给方法的参数的实际值?

【问题讨论】:

【参考方案1】:

虽然参数类型实际上是 System.Boolean,但 FxCop IL 解析器将其视为整数。这是应该起作用的规则的简化版本(假设您希望非文字 endResponse 值触发规则违规):

    public override ProblemCollection Check(Member member)
    
        Method method = member as Method;
        if (method != null)
        
            this.Visit(method.Body);
        

        return this.Problems;
    

    public override void VisitMethodCall(MethodCall call)
    
        base.VisitMethodCall(call);

        Method targetMethod = (Method)((MemberBinding)call.Callee).BoundMember;
        if (targetMethod.DeclaringType.FullName.Equals("System.Web.HttpResponse", StringComparison.Ordinal) &&
            targetMethod.Name.Name.Equals("Redirect", StringComparison.Ordinal))
        
            bool callIsAcceptable = false;

            if (targetMethod.Parameters.Count == 2)
            
                Expression endResponseOperand = call.Operands[1];
                if (endResponseOperand.NodeType == NodeType.Literal)
                
                    if ((int)((Literal)endResponseOperand).Value == 1)
                    
                        callIsAcceptable = true;
                    
                
            

            if (!callIsAcceptable)
            
                this.Problems.Add(new Problem(this.GetResolution(), call));
            
        
    

【讨论】:

这行得通,谢谢!我将其更改为 .Value == 0 因为这就是我们想要的。另外,我注意到,如果在一种方法中有两个违反此规则的行为,则两者都会添加到 Problems 集合中,但 FxCop 中只显示一个。如果我随后修复了第一个违规行为,那么当我进行新的分析时,第二个违规行为就会显示出来。除此之外,它可以工作,我们可以使用此代码。谢谢。 FxCop UI 应用程序按其目标对违规行为进行分组。如果查看消息的问题列表,您将看到完整的违规列表。 奇怪,我在一个测试项目中遇到了这个问题。将代码放入实际项目时,我得到了所有正确的错误。无论如何感谢所有的帮助!

以上是关于如何在 FxCop 的自定义规则中获取传递给方法的参数值?的主要内容,如果未能解决你的问题,请参考以下文章

FxCop:检查程序集信息值的自定义规则

如何编写代码分析 (FxCop) 规则以防止方法调用

FxCop 规则确保在测试中首先调用某个接受 lambda 的方法

使用 SonarQube 自定义 Fxcop 规则

Fxcop 针对 VS 2010 设计的自定义代码不适用于 VS 2012

是否有自定义 FxCop 规则可以检测未使用的 PUBLIC 方法?