2

c# 如何使参数工作。

当您有类似的代码时

 static string Concat(int arg)
 {
     return arg.ToString();
 }

static string Concat(int arg, params string[] p)
{
    string result = string.Empty;
    result = result + arg.ToString();
    foreach (var s in p)
    {
        result = result + s;
    }
    return result;
}

Resharper 说带有参数的方法隐藏了另一种方法。这是否意味着在引擎盖下正在定义另一种方法并调用带有传递空数组的参数的方法?还是完全不同的东西?

(请不要陷入蹩脚的代码 - 这只是一个例子)

编辑解释:

如果我没有定义静态字符串 Concat(int arg) 方法,我仍然可以将第二个称为

var s = Concat(123);

尽管没有定义该方法....所以问题是:第一个方法是在后台隐式定义的,并使用空数组调用第二个方法。请注意,我将 arg 类型从 string 更改为 int。

解释我所看到的奇怪之处。当您按上述方式调用时...它使用空数组命中 params 对象,param 不为空 - 这是我所期望的。当我第一次编写 foreach 循环时,我对参数进行了空检查,然后发现我不需要它。

所以......你的理由是它必须在数组中的第一个参数之后包装任何参数,对吗?一点内联代码?...因此,如果您传入“dave”,您将获得 freddave 作为输出 ....

但是将 null 传递给它....

static void Main(string[] args)
{
    Console.WriteLine(Concat("fred",null));
}

 //static string Concat(string arg)
 //{
 //    return arg;
 //}

static string Concat(string arg, params int[] p)
{
    string result = string.Empty;
    result = result + arg;
    if (p != null)
    {
        foreach (var s in p)
        {
            result = result + s.ToString();
        }
    }

    return result;
}

并且您发现在这种情况下 p 实际上为 null ...如果您使用字符串示例 ... id of expected an array with 1 element of null ... 而整个 params 对象为空。

4

1 回答 1

4

老实说,我认为在这里称其为“隐藏”是一种误导。

这两种方法都是肯定创建的,但如果你调用:

Concat(5);

那么对于该调用,两种方法都适用(在 C# 规范第 7.5.3.1 节的术语中),但第一种方法更好(第 7.5.3.2 节),因为:

  • 否则,如果 M P适用于其范式且 M Q有一个params数组且仅适用于其扩展形式,则 M P优于 M Q

因此,在这种情况下,将调用第一个方法。

params如果不指定至少一个字符串,则无法使用扩展调用第二种方法。当然,它仍然可以用空数组调用:

Concat(5, new string[0]);
于 2013-10-04T09:07:00.450 回答