Полное руководство. С# 4.0 - Шилдт Герберт
Шрифт:
Интервал:
Закладка:
static void OptArgMeth(int alpha, int beta=10, int gamma = 20) {В этой строке кода объявляются два необязательных параметра: beta и gamma, причем параметру beta по умолчанию присваивается значение 10, а параметру gamma —значение 20. Эти значения используются по умолчанию, если для данных параметровне указываются аргументы при вызове метода. Следует также иметь в виду, что параметр alpha не является необязательным. Напротив, это обычный параметр, для которого всегда нужно указывать аргумент.Принимая во внимание приведенное выше объявление метода OptArgMeth(),последний можно вызвать следующими способами.
// Передать все аргументы явным образом.OptArgMeth(1, 2, 3);// Сделать аргумент gamma необязательным.OptArgMeth(1, 2);// Сделать оба аргумента beta и gamma необязательными.OptArgMeth(1);При первом вызове параметру alpha передается значение 1, параметру beta —значение 2, а параметру gamma — значение 3. Таким образом, все три аргумента задаются явным образом, а значения, устанавливаемые по умолчанию, не используются.При втором вызове параметру alpha передается значение 1, а параметру beta — значение 2, но параметру gamma присваивается устанавливаемое по умолчанию значение20. И наконец, при третьем вызове упомянутого выше метода параметру alpha передается значение 1, а параметрам beta и gamma присваиваются устанавливаемые поумолчанию значения. Следует, однако, иметь в виду, что параметр beta не получитустанавливаемое по умолчанию значение, если то же самое не произойдет с параметром gamma. Если первый аргумент устанавливается по умолчанию, то и все остальныеаргументы должны быть установлены по умолчанию.Весь описанный выше процесс демонстрируется в приведенном ниже примерепрограммы.
// Продемонстрировать необязательные аргументы.using System;class OptionArgDemo { static void OptArgMeth(int alpha, int beta=10, int gamma = 20) { Console.WriteLine("Это аргументы alpha, beta и gamma: " + alpha + " " + beta + " " + gamma); } static void Main() { // Передать все аргументы явным образом. OptArgMeth(1,2,3); // Сделать аргумент gamma необязательным. OptArgMeth(1, 2); // Сделать оба аргумента beta и gamma необязательными. OptArgMeth(1); }}Результат выполнения данной программы лишь подтверждает применение используемых по умолчанию аргументов.
Это аргументы alpha, beta и gamma: 1 2 3Это аргументы alpha, beta и gamma: 1 2 20Это аргументы alpha, beta и gamma: 1 10 20Как следует из приведенного выше результата, если аргумент не указан, то используется его значение, устанавливаемое по умолчанию.Следует иметь в виду, что все необязательные аргументы должны непременно указываться справа от обязательных. Например, следующее объявление оказывается недействительным.
int Sample(string name = "пользователь", int userid) { // Ошибка!Для исправления ошибки в этом объявлении необходимо указать аргумент userIdдо аргумента name. Раз уж вы начали объявлять необязательные аргументы, то указывать после них обязательные аргументы нельзя. Например, следующее объявлениетакже оказывается неверным.
int Sample(int accountId, string name = "пользователь", int userId) { // Ошибка!Аргумент name объявляется как необязательный, и поэтому аргумент userId следует указать до аргумента name (или же сделать его также необязательным).Помимо методов, необязательные аргументы можно применять в конструкторах, индексаторах и делегатах. (Об индексаторах и делегатах речь пойдет далее в этой книге.)Преимущество необязательных аргументов заключается, в частности, в том, чтоони упрощают программирующему обращение со сложными вызовами методов иконструкторов. Ведь нередко в методе приходится задавать больше параметров, чемобычно требуется. И в подобных случаях некоторые из этих параметров могут бытьсделаны необязательными благодаря аккуратному применению необязательных аргументов. Это означает, что передавать нужно лишь те аргументы, которые важны вданном конкретном случае, а не все аргументы, которые в противном случае должныбыть обязательными. Такой подход позволяет рационализировать метод и упроститьпрограммирующему обращение с ним.### Необязательные аргументы и перегрузка методовВ некоторых случаях необязательные аргументы могут стать альтернативой перегрузке методов. Для того чтобы стало понятнее, почему это возможно, обратимся ещераз к примеру метода OptArgMeth(). До появления в C# необязательных аргументовнам пришлось бы создать три разных варианта метода OptArgMeth(), чтобы добитьсятаких же функциональных возможностей, как и у рассмотренного выше варианта этого метода. Все эти варианты пришлось бы объявить следующим образом.
static void OptArgMeth(int alpha)static void OptArgMeth(int alpha, int beta)static void OptArgMeth(int alpha, int beta, int gamma)Эти перегружаемые варианты метода OptArgMeth() позволяют вызывать его с одним, двумя или тремя аргументами. (Если значения параметров beta и gamma не передаются, то они предоставляются в теле перегружаемых вариантов данного метода.) Безусловно, в такой реализации функциональных возможностей метода OptArgMeth()с помощью перегрузки нет ничего дурного. Но в данном случае целесообразнее все жевоспользоваться необязательными аргументами, хотя такой подход не всегда оказывается более совершенным, чем перегрузка метода.### Необязательные аргументы и неоднозначностьПри использовании необязательных аргументов может возникнуть такое затруднение, как неоднозначность. Нечто подобное может произойти при перегрузке методас необязательными параметрами. В некоторых случаях компилятор может оказаться не в состоянии определить, какой именно вариант метода следует вызывать, когданеобязательные аргументы не заданы. В качестве примера рассмотрим два следующихварианта метода OptArgMeth().
static void OptArgMeth(int alpha, int beta=10, int gamma = 20) { Console.WriteLine("Это аргументы alpha, beta и gamma: " + alpha + " " + beta + " " + gamma);}static void OptArgMeth(int alpha, double beta=10.0, double gamma = 20.0) { Console.WriteLine("Это аргументы alpha, beta и gamma: " + alpha + " " + beta + " " + gamma);}Обратите внимание на то, что единственное отличие в обоих вариантах рассматриваемого здесь метода состоит в типах параметров beta и gamma, которые оказываютсянеобязательными. В первом варианте оба параметра относятся к типу int, а во втором — к типу double. С учетом этих вариантов перегрузки метода OptArgMeth()следующий его вызов приводит к неоднозначности.
OptArgMeth(1); // Ошибка из-за неоднозначности!Этот вызов приводит к неоднозначности потому, что компилятору неизвестно, какой именно вариант данного метода использовать: тот, где параметры beta и gammaимеют тип int, или же тот, где они имеют тип double. Но самое главное, что конкретный вызов метода OptArgMeth() может привести к неоднозначности, даже если онаи не присуща его перегрузке.В связи с тем что перегрузка методов, допускающих применение необязательныхаргументов, может привести к неоднозначности, очень важно принимать во вниманиепоследствия такой перегрузки. В некоторых случаях, возможно, придется отказатьсяот применения необязательных аргументов, чтобы исключить неоднозначность и темсамым предотвратить использование метода непреднамеренным образом.### Практический пример использования необязательных аргументовДля того чтобы показать на практике, насколько необязательные аргументы упрощают вызовы некоторых типов методов, рассмотрим следующий пример программы.В этой программе объявляется метод Display(), выводящий на экран символьнуюстроку полностью или частично.
// Использовать необязательный аргумент, чтобы упростить вызов метода.using System;
class UseOptArgs { // Вывести на экран символьную строку полностью или частично. static void Display(string str, int start = 0, int stop = -1) { if (stop < 0) stop = str.Length; // Проверить условие выхода за заданные пределы. if(stop > str.Length | start > stop | start < 0) return; for(int i=start; i < stop; i++) Console.Write(str[i]); Console.WriteLine(); } static void Main() { Display("это простой тест"); Display("это простой тест", 12); Display("это простой тест", 4, 14); }}Выполнение этой программы дает следующий результат.