2013-12-10 2 views
1
void Main() 
{ 
    //Thing(x:1, s:string.Empty, hello:new Hello(), new Hello()); 
    Thing(x:1, s:string.Empty, hello:new[]{ new Hello(), new Hello()}); 
} 

public void Thing(int x, string s = "", params Hello[] hello) 
{ 
} 

public class Hello { } 

Почему мне нужно указать массив, чтобы заставить params работать при использовании с необязательным аргументом или я? Использовались этикетки только причина в том, что я изначально хотел, чтобы исключить дополнительный параметрЯвный массив для параметров с необязательными аргументами?

+1

Даже Джон Скит не смог придумать объяснения :) http://stackoverflow.com/questions/12747117/optional-argument-followed-by-params?rq=1 – Matten

ответ

1

Так как params работает - технически это параметр массива, который компилятор будет генерировать из списка аргументов для вас. Текущие спецификации C# не поддерживают передачу нескольких значений в один именованный параметр без их связывания. Если вы хотите использовать имя параметра для массового нескольких значений, вам необходимо расслоить параметры в массиве.

Они должны работать:

Thing(x:1, hello:new[]{ new Hello(), new Hello()}); // 2 values 
Thing(x:1, hello:new Hello()); // one value 
Thing(x:1); // no values 

Если вы думаете, что это ценным дополнение к компилятору относительно стоил требуется для его реализации, то не стесняйтесь оставить предложение на Microsoft Connect

+0

@D Stanley. Помимо этого, это текущая реализация компилятора, есть ли объяснение? –

+0

Никто не реализовал его в компиляторе - вот в чем причина. Я предполагаю, что это никому не предлагалось, или предоставленная _value_ не оправдывает _cost_ ее реализации - либо по альтернативной стоимости, технической стоимости, либо по влиянию на другие функции. Особенности не являются бесплатными. –

+1

@Jaycee Я могу придумать несколько более насущных улучшений, вы можете перегружать свои функции. – Jodrell

1

вы могли бы просто сделать,

Thing(1, string.Empty, new Hello(), new Hello()); 

, так как вы используете params.

В этом отношении все это было бы совместимо.

Thing(1); 
Thing(2, string.Empty); 
Thing(3, string.Empty, null); 
Thing(4, string.Empty, new Hello()); 
Thing(-69, "negative feeback", new Hello(), null); 
Thing(42, "the meaning of life", new Hello(), new Hello()); 
Thing(666, theBeast.ToString(), new Hello(), new Hello(), new Hello()); 
// etc. etc. 

Ваш комментарий Я думаю, что ваш вопрос на самом деле,

Почему я должен построить params массив, используя имена параметров?

Этот вопрос является duplicate, но, в целом его потому, что это так.


Если вы хотите, чтобы пропустить s и получить преимущества params почему бы не объявить перегрузки,

public void Thing(int x, string s = "", params Hello[] hellos) 
{ 
} 

public void Thing(int x, params Hello[] hellos) 
{ 
    this.Thing(x, string.Empty, hellos); 
} 

Тогда вы все еще можете использовать params как предполагалось, и вы не должны использовать имена параметров ,

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

+1

Вы правы, но я догадаться, что реальный вопрос заключается в том, почему он должен явно выделять массив «Hello», а не передавать несколько объектов «Hello» при использовании именованных параметров – Abbas

+1

... когда op использует имена параметров. – Matten

+0

@Jodrell True, но я хотел исключить второй параметр и более техническое объяснение, если это возможно. Благодарю. –

1

Ну, именованные аргументы и params имеют противоречивые правила: Именованные аргументы могут отображаться в любом порядке, а params должен быть в конце. Согласно первому, мы должны быть в состоянии сделать это:

Thing(1, hello:new Hello(), new Hello(), s:string.Empty); 

компилятор, безусловно, может работать, как интерпретировать это, но это менее понятно для читателя, чем с Params в конце, как они обычно являются. Но если hello: был вынужден быть помещен в конец, это было бы несовместимо с именованными аргументами и устранить некоторую гибкость, которую вы в противном случае имели бы.

Итак, я считаю, что требующий явного массива является компромиссом, который сохраняет самую согласованность.

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