Добавить в цитаты Настройки чтения

Страница 107 из 502

При использовании необязательных аргументов может возникнуть такое затруднение, как неоднозначность. Нечто подобное может произойти при перегрузке метода с необязательными параметрами. В некоторых случаях компилятор может оказаться не в состоянии определить, какой именно вариант метода следует вызывать, когда необязательные аргументы не заданы. В качестве примера рассмотрим два следующих варианта метода OptArgMeth().

<b>static void OptArgMeth(int alpha, int beta=10, int gamma = 20) {</b>

<b>  Console.WriteLine(&quot;Это аргументы alpha, beta и gamma: &quot; </b>

<b>         + alpha + &quot; &quot; + beta + &quot; &quot; + gamma);</b>

<b>}</b>

<b>static void OptArgMeth(int alpha, double beta=10.0, double gamma =20.0) {</b>

<b>  Console.WriteLine(&quot;Это аргументы alpha, beta и gamma: &quot; </b>

<b>         + alpha + &quot; &quot; + beta + &quot; &quot; + gamma);</b>

<b>}</b>

Обратите внимание на то, что единственное отличие в обоих вариантах рассматриваемого здесь метода состоит в типах параметров beta и gamma, которые оказываются необязательными. В первом варианте оба параметра относятся к типу int, а во втором — к типу double. С учетом этих вариантов перегрузки метода OptArgMeth() следующий его вызов приводит к неоднозначности.

<b>OptArgMeth(1); // Ошибка из-за неоднозначности!</b>

Этот вызов приводит к неоднозначности потому, что компилятору неизвестно, какой именно вариант данного метода использовать: тот, где параметры beta и gamma имеют тип int, или же тот, где они имеют тип double. Но самое главное, что конкретный вызов метода OptArgMeth() может привести к неоднозначности, даже если она и не присуща его перегрузке.

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

Для того чтобы показать на практике, насколько необязательные аргументы упрощают вызовы некоторых типов методов, рассмотрим следующий пример программы. В этой программе объявляется метод Display(), выводящий на экран символьную строку полностью или частично.

<b>// Использовать необязательный аргумент, чтобы упростить вызов метода.</b>

<b>using System;</b>

<b>class UseOptArgs {</b>

<b>// Вывести на экран символьную строку полностью или частично. </b>

<b>  static void Display(string str, int start = 0, int stop = -1) {</b>

<b>    if(stop &lt; 0)</b>

<b>      stop = str.Length;</b>

<b>    // Проверить условие выхода за заданные пределы. </b>

<b>    if(stop &gt; str.Length | start &gt; stop | start &lt; 0) return;</b>

<b>    for (int i=start; i &lt; stop; i++)</b>

<b>      Console.Write(str[i] ) ;</b>

<b>    Console.WriteLine();</b>

<b>  }</b>

<b>  static void Main() {</b>

<b>    Display(&quot;это простой тест&quot;);</b>

<b>    Display(&quot;это простой тест&quot;, 12);</b>

<b>    Display(&quot;3TO простой тест&quot;, 4, 14);</b>

<b>  }</b>

<b>}</b>

Выполнение этой программы дает следующий результат.

<b>это простой тест </b>

<b>тест</b>

<b>простой те</b>

Внимательно проанализируем метод Display(). Выводимая на экран символьная строка передается в первом аргументе данного метода. Это обязательный аргумент, а два других аргумента — необязательные. Они задают начальный и конечный индексы для вывода части символьной строки. Если параметру stop не передается значение, то по умолчанию он принимает значение -1, указывающее на то, что конечной точкой вывода служит конец символьной строки. Если же параметру start не передается значение, то по умолчанию он принимает значение 0. Следовательно, в отсутствие одного из необязательных аргументов символьная строка выводится на экран полностью. В противном случае она выводится на экран частично. Это означает, что если вызвать метод Display() с одним аргументом (т.е. с выводимой строкой), то символьная строка будет выведена на экран полностью. Если же вызвать метод Display() с двумя аргументами, то на экран будут выведены символы, начиная с позиции, определяемой аргументом start, и до самого конца строки. А если вызвать метод Display() с тремя аргументами, то на экран будут выведены символы из строки, начиная с позиции, определяемой аргументом start, и заканчивая позицией, определяемой аргументом stop.

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