CodeQL 文档

“ref” 参数过多

ID: cs/too-many-ref-parameters
Kind: problem
Security severity: 
Severity: recommendation
Precision: very-high
Tags:
   - testability
   - readability
Query suites:
   - csharp-security-and-quality.qls

点击查看 CodeQL 存储库中的查询

虽然使用 ref 传递方法参数有时是一种明智的做法(典型的例子是编写“交换”方法时),但过度使用引用参数会使方法不必要地难以理解和调用。

方法最终依赖于在其他地方正确初始化其参数,并且可能存在诸如别名之类的问题(当两个参数引用同一个对象时)。它们可能难以调用,因为引用必须引用左值(而不是临时对象),因此必须创建额外的对象来保存调用的结果。它们的结果也可能难以转发给其他方法。

建议

虽然并非在所有情况下都适用,并且必须加以判断,但一种常见的解决方案是创建一个新类,该类包装您尝试在方法中设置的值,然后修改该方法以返回它的新实例。

示例

在本例中,填充 nameaddresstel 字段是通过采用 ref 参数的方法完成的。这不是很好的做法,并且会使方法混乱。

using System;

class Bad
{
    private static void PopulateDetails(ref string name, ref string address, ref string tel)
    {
        name = "Foo";
        address = "23 Bar Street";
        tel = "01234 567890";
    }

    private static void PrintDetails(string name, string address, string tel)
    {
        Console.WriteLine("Name: " + name);
        Console.WriteLine("Address: " + address);
        Console.WriteLine("Tel.: " + tel);
    }

    static void Main(string[] args)
    {
        string name = null, address = null, tel = null;
        PopulateDetails(ref name, ref address, ref tel);
        PrintDetails(name, address, tel);
    }
}

最好将值包装在它们自己的 Details 类中,然后返回 Details 的新实例。它更容易正确传递给其他函数,也更容易理解。

using System;

class Good
{
    class Details
    {
        public string Name { get; private set; }
        public string Address { get; private set; }
        public string Tel { get; private set; }

        public Details(string name, string address, string tel)
        {
            Name = name;
            Address = address;
            Tel = tel;
        }
    }

    private static Details PopulateDetails()
    {
        return new Details("Foo", "23 Bar Street", "01234 567890");
    }

    private static void PrintDetails(Details details)
    {
        Console.WriteLine("Name: " + details.Name);
        Console.WriteLine("Address: " + details.Address);
        Console.WriteLine("Tel.: " + details.Tel);
    }

    static void Main(string[] args)
    {
        PrintDetails(PopulateDetails());
    }
}
  • ©GitHub 公司
  • 条款
  • 隐私