2009-09-25 2 views
8

Я только что встретил что-то с C# сегодня, о котором я раньше не думал. У меня есть два метода в моем классе, один - перегрузка другого. Они объявлены следующим образом:C# params ключевое слово с двумя параметрами того же типа

1) public void RequirePermissions(params string[] permissions)... 
2) public void RequirePermissions(string message, params string[] permissions)... 

В моем коде, я попытался назвать первый, как так:

RequirePermissions("Permission1", "Permission2"); 

... Главное, чтобы вызвать первую перегрузку. Ну, это называется второй перегрузкой. Единственный способ, которым я могу получить его, чтобы вызвать первый метод в этом случае вручную передать строку [] объект следующим образом:

RequirePermissions(new string[] { "Permission1", "Permission2" }); 

Теперь это поведение не смущает меня, потому что я понимаю, что компилятор может 't скажите, какой метод я действительно хотел вызвать на основе моих предоставленных параметров. Но не был ли я осторожен, это могло остаться незамеченным в моем коде. Кажется, Microsoft должна была заставить компилятор выбросить ошибку, когда она столкнулась с ситуацией, подобной выше. У кого-нибудь есть мысли по этому поводу? Есть ли другой способ вызвать первую перегрузку, отличную от «решения», которую я опубликовал?

+0

Посмотрите здесь http://ayende.com/Blog/archive/2007/12/31/Tricky-Code.aspx и здесь http: //www.yoda.arachsys ,com/csharp/teasers.html (no 6) – RichardOD

+1

Я немного смущен вашим предложением. Считаете ли вы, что предупреждение должно быть вызвано двусмысленным * вызовом * или набором * деклараций *, которые могут привести к двусмысленному звонку? –

ответ

2

Да, я согласен, что это должно быть предупреждение при использовании массивов аргументов переменной длины вызывает неоднозначную перегрузку - это очень важный вопрос, и люди почти наверняка не хотят создавать такие ситуации.

Я также не знаю никоим образом, кроме того, что вы опубликовали, чтобы избежать возникающего разрешения вызова, кроме как избежать этого, в первую очередь, что я бы очень рекомендовал!

0

Вы не можете использовать параметры и быть явным с вашими подписями.

public void RequirePermissions(string[] permissions)... 
public void RequirePermissions(string message, string[] permissions).. 
7

Соглашаясь с Адамом, я бы изменить его на что-то вроде:

public void RequirePermissions(params string[] permissions) 

public void RequirePermissionsWithMessage(string message, params string[] permissions) 
+0

Черт, не заметил вашего ответа, пока я не разместил свой. Полагаю, полосы прокрутки в образцах кода заставляют мои глаза оглядываться. – MusiGenesis

+0

@scottm: по-видимому, нет. * Я * проголосовал * ваш * ответ. :) – MusiGenesis

7

Лично я хотел бы сделать это следующим образом:

1) public void RequirePermissions(params string[] permissions)... 
2) public void RequireMessageAndPermissions(string message, 
     params string[] permissions)... 

Люди падают слишком влюблены иногда перегрузка, и когда вы сочетаете это с любовью к ключевому слову params, вы просто увеличиваете уровень путаницы для тех, кому в конечном итоге придется взять на себя ваш код.

+0

+1 Хорошая идея, еще более явная –

3

Похоже, что другого выхода нет.

Вы можете найти объяснение этому поведению в C# спецификации http://www.jaggersoft.com/csharp_standard /17.5.1.4.htm и здесь http://www.jaggersoft.com/csharp_standard/14.4.2.1.htm (пункт 2)

массив параметров точности эквивалентно параметру значения (§17.5.1.1) одного и того же типа.

и

Расширенная форма методы доступен только если нормальная форма методы не применимо и только если метод с той же сигнатурой, что и расширенной форма еще не объявлены в том же виде

Смежные вопросы