2013-06-17 4 views
9

Каковы правила при разрешении переменной количества параметров, переданных params?Решающие параметры в C#

Предположим, что у меня есть код:

public void Method(params object[] objects) { } 

public void Method(IMyInterface intf, params object[] objects) { } 

Как Method(a, b, c) разрешенное, если это IMyInterface? Могу ли я быть уверенным, что C# всегда будет пытаться выбрать наиболее подходящую перегрузку?

+0

Care прокомментировать downvote? – Spook

ответ

11

Это отвечает на C# язык спецификации:

7.5.3.1 Применяемое член функция

[...]

  • В противном случае, если MP применяется в его нормальная форма и MQ имеет массив параметров и применим только в расширенной форме, тогда MP лучше, чем MQ.

  • В противном случае, если MP имеет более объявленные параметры, чем MQ, тогда MP равен лучше, чем MQ. Это может произойти, если оба метода имеют params массивы и применимы только в их расширенных формах.

[...]

В вашем примере оба перегруженных будут применяться только в своих расширенных формах. Поскольку у второго есть более заявленные параметры, это будет лучше.

В контексте спецификации, одна перегрузки быть лучше, чем все остальные означает, что компилятор выбирает его, чтобы связать вызов, как это произойдет в примере на стадии обсуждения (если не одна перегрузки не лучше, чем все другие, результатом является ошибка времени компиляции из-за двусмысленности).

+0

Что такое расширенная форма параметров метода? –

+0

@gmailuser: В терминах непрофессионала вы используете «расширенную форму», если удаление «параметров» из определения метода приведет к тому, что вызов метода не будет компилироваться. Принимая первую перегрузку, 'Method (new object [] {" foo "})' является нормальной формой, потому что формальный аргумент является 'object []', и это то, что вы проходите. 'Method (" foo ")' является расширенной формой, потому что вы полагаетесь на компилятор для создания 'object []' для вас, и это было бы невозможно без 'params'. – Jon

3

Смотрите также C# Spec. 17.5.1.4 regarding Parameter arrays

При выполнении разрешения перегрузки, метод с параметром массив может быть применим либо в его нормальной форме или в его расширенной форме (§14.4.2.1). 2 Расширенная форма метода доступна только в том случае, если нормальная форма метода неприменима и только если метод с та же самая подпись, что и расширенная форма, еще не объявлена ​​в того же типа.

Пример

using System; 
class Test 
{ 
    static void F(params object[] a) { 
     Console.WriteLine("F(object[])"); 
    } 
    static void F() { 
     Console.WriteLine("F()"); 
    } 
    static void F(object a0, object a1) { 
     Console.WriteLine("F(object,object)"); 
    } 
    static void Main() { 
     F(); 
     F(1); 
     F(1, 2); 
     F(1, 2, 3); 
     F(1, 2, 3, 4); 
    } 
} 

производит выход:

F(); 
F(object[]); 
F(object,object); 
F(object[]); 
F(object[]); 
Смежные вопросы