Метод: именованные и необязательные аргументы 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Метод: именованные и необязательные аргументы



 

В Visual C# 2010 появились именованные и необязательные аргументы. Именованные аргументы позволяют указать аргумент для определенного параметра, связав аргумент с именем параметра, а не с позицией параметра в списке параметров. Необязательные аргументы позволяют опускать аргументы для некоторых параметров. Оба подхода можно применять к методам, индексаторам, конструкторам и делегатам.

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

При совместном использовании именованных и необязательных параметров разработчик может задавать аргументы лишь для некоторых параметров из списка необязательных параметров. Эта возможность значительно упрощает вызов интерфейсов COM, например интерфейсов API автоматизации Microsoft Office.

 

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

 

CalculateBMI(123, 64);

 

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

 

CalculateBMI(weight: 123, height: 64);

CalculateBMI(height: 64, weight: 123);

 

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

Именованный аргумент можно поместить после позиционных аргументов, как показано ниже:

 

CalculateBMI(123, height: 64);

 

Однако позиционные аргументы нельзя размещать после именованных аргументов. Следующая инструкция вызывает ошибку компилятора:

 

CalculateBMI(weight: 123, 64);

 

Код реализации примеров выше:

 

class NamedExample

{

static void Main(string[] args)

{

// Метод с нормальным вызовом (позиции аргументов на месте)

Console.WriteLine(CalculateBMI(123, 64));

// Именованные аргументы с именами

Console.WriteLine(CalculateBMI(weight: 123, height: 64));

Console.WriteLine(CalculateBMI(height: 64, weight: 123));

// Позиционные аргументы после именованных

//Console.WriteLine(CalculateBMI(weight: 123, 64));

// Именованные аргументы после позиционных

Console.WriteLine(CalculateBMI(123, height: 64));

}

 

static int CalculateBMI(int weight, int height)

{

return (weight * 703) / (height * height);

}

}

 

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

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

Необязательные параметры определяются в конце списка параметров после всех обязательных параметров. Если вызывающий объект задает аргумент для какого-либо из последующих необязательных параметров, он должен задать аргументы для всех предшествующих необязательных параметров. Разделённые запятыми пустые позиции в списке аргументов не поддерживаются. Например, в следующем коде метод экземпляра ExampleMethod определён одним или двумя необязательными параметрами:

 

public void ExampleMethod(int required,

string optionalstr = "Строка по умолчанию", int optionalint = 10)

 

Следующий вызов ExampleMethod вызывает ошибку компилятора, поскольку аргумент предоставлен для третьего параметра, а не для второго:

 

anExample.ExampleMethod(3,,4);

 

Но если имя третьего параметра известно, задачу можно выполнить с использованием именованного аргумента:

 

anExample.ExampleMethod(3, optionalint: 4);

 

IntelliSense использует квадратные скобки для указания необязательных параметров:

 

Рис. 1. Подсветка IntelliSense при вызове метода ExampleMethod (A ― специальный пустой класс с методом)

 

В следующем примере у конструктора класса ExampleClass имеется один параметр, который является необязательным. У метода экземпляра ExampleMethod имеется один обязательный параметр required и два необязательных параметра optionalstr и optionalint. В коде в методе Main показаны различные способы вызова конструктора и метода:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace LC_Console

{

namespace OptionalNamespace

{

class OptionalExample

{

static void Main()

{

ExampleClass anExample = new ExampleClass();

anExample.ExampleMethod(1, "Один", 1);

anExample.ExampleMethod(2, "Два");

anExample.ExampleMethod(3);

// Пример anotherExample отправляет аргумент опционального параметра в конструктор

ExampleClass anotherExample = new ExampleClass("Имя");

anotherExample.ExampleMethod(1, "Один", 1);

anotherExample.ExampleMethod(2, "Два");

anotherExample.ExampleMethod(3);

 

// Код ниже вызовет ошибки

 

// Аргумент должен быть предоставлен для первого параметра, и это

// должно быть целое число

//anExample.ExampleMethod("Один", 1);

//anExample.ExampleMethod();

 

// Нельзя оставить зазор в предоставляемых аргументах

//anExample.ExampleMethod(3,,4);

//anExample.ExampleMethod(3, 4);

 

// А с импользованием имён аргументов код заработает

anExample.ExampleMethod(3, optionalint: 4);

Console.WriteLine("Для продолжения нажмите любую клавишу...");;

Console.ReadKey();

}

}

 

class ExampleClass

{

private string _name;

 

// Because the parameter for the constructor, name, has a default

// value assigned to it, it is optional.

public ExampleClass(string name = "Имя по умолчанию")

{

_name = name;

}

 

// The first parameter, required, has no default value assigned

// to it. Therefore, it is not optional. Both optionalstr and

// optionalint have default values assigned to them. They are optional.

public void ExampleMethod(int required, string optionalstr = "Строка по умолчанию",

int optionalint = 10)

{

Console.WriteLine("{0}: {1}, {2}, и {3}", _name, required, optionalstr,

optionalint);

}

}

}

}

/* Выведет:

* Имя по умолчанию: 1, Один, и 1.

* Имя по умолчанию: 2, Два, и 10.

* Имя по умолчанию: 3, Строка по умолчанию, и 10.

* Имя: 1, Один, и 1.

* Имя: 2, Два, и 10.

* Имя: 3, Строка по умолчанию, и 10.

* Имя по умолчанию: 3, Строка по умолчанию, и 4.

*/

 

Именованные и необязательные аргументы, а также поддержка динамических объектов и другие усовершенствования значительно улучшаю взаимодействие с интерфейсами API COM, например с API автоматизации Office.

Например, у метода AutoFormat в интерфейсе Microsoft Office ExcelRange имеется семь параметров, все из которых необязательны.

 

Использование именованных и необязательных аргументов следующим образом влияет на разрешение перегрузки:

  • метод, индексатор или конструктор является кандидатом на выполнение, если каждый из его параметров является необязательным или соответствует по имени или позиции одному аргументу в инструкции вызова, а этот аргумент можно преобразовать к типу параметра;
  • если обнаружено более одного кандидата, правила разрешения перегрузки для предпочтительных преобразований применяются к аргументам, которые заданы в явном виде. Опущенные аргументы для необязательных параметров игнорируются;
  • если два кандидата оказываются одинаково подходящими, предпочтение отдаётся кандидату, у которого нет необязательных параметров, аргументы которых были опущены в вызове. Это последовательность общего приоритета при разрешении перегрузки для кандидатов с меньшим числом параметров.

 

3.7.3. Метод: процедура или функция?!

Метод: процедура или функция?!

 

Все функции и процедуры в теоретических материалах учебного курса представлены как методы. Но фактически, можно разделить методы на две составные части: функции и процедуры.

 

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

Функция ― это такая же процедура, только ей свойственно явное возвращение результат её работы (ключевое слово return).

 

Ниже представлено два метода:

 

static void CopyString(string a, ref string b)

{

b = a + b;

}

 

static string ReturnString(string a, string b)

{

return a + b;

}

 

Из анализа приведённого выше кода видно, что процедура CopyString – не возвращает значений с помощью слова return, то есть напрямую. Она неявно возвращает и изменяет значение по ссылке через ref. Внизу же у нас функция.

 

Процедура в общем случае:

 

<модификатор доступа> void <название> (параметры)

{

// Тело процедуры

}

 

Функция в общем случае:

 

<модификатор доступа> <тип, кроме void> <название> (параметры)

{

// Тело функции

return <тип>;

}

 

Метод: рекурсия

Метод: рекурсия

 

В С# допускается, чтобы метод вызывал самого себя. Этот процесс называется рекурсией, а метод, вызывающий самого себя, — рекурсивным. Вообще, рекурсия представляет собой процесс, в ходе которого нечто определяет само себя. В этом отношении она чем-то напоминает циклическое определение. Рекурсивный метод отличается главным образом тем, что он содержит оператор, в котором этот метод вызывает самого себя. Рекурсия является эффективным механизмом управления программой.

 

Классическим примером рекурсии служит вычисление факториала числа:

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace LC_Console

{

class Program

{

// Рекурсивный метод

static int factorial(int i)

{

int result;

if (i == 1)

return 1;

result = factorial(i - 1) * i;

return result;

}

 

static void Main(string[] args)

{

label1:

Console.WriteLine("Введите число: ");

 

try

{

int i = int.Parse(Console.ReadLine());

Console.WriteLine("{0}! = {1}", i, factorial(i));

}

catch (FormatException)

{

Console.WriteLine("Неккоректное число");

goto label1;

}

Console.WriteLine("Для продолжения нажмите любую клавишу...");

Console.ReadKey();

}

}

}

}

/* Выведет:

* Введите число:

*:3

* 3! = 6

* Для продолжения нажмите любую клавишу...

*/

 

Обратим внимание, что рекурсивный метод factorial вызывает сам себя, при этом переменная i с каждым вызовом уменьшается на 1.

Рекурсивные варианты многих процедур могут выполняться немного медленнее, чем их итерационные эквиваленты из-за дополнительных затрат системных ресурсов на неоднократные вызовы метода. Если же таких вызовов окажется слишком много, то в конечном итоге может быть переполнен системный стек. А поскольку параметры и локальные переменные рекурсивного метода хранятся в системном стеке и при каждом новом вызове этого метода создается их новая копия, то в какой-то момент стек может оказаться исчерпанным. В этом случае возникает исключительная ситуация, и общеязыковая исполняющая среда (CLR) генерирует соответствующее исключение. Но беспокоиться об этом придется лишь в том случае, если рекурсивная процедура выполняется неправильно.

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

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

Понятие «Свойство»

Понятие «Свойство»

 

Понятие «Свойство»

 

Свойство — это член, предоставляющий гибкий механизм для чтения, записи или вычисления значения частного поля (переменной). Свойства можно использовать, как если бы они являлись открытыми членами данных, хотя в действительности они являются специальными методами, называемыми методами доступа. Это обеспечивает простой доступ к данным и позволяет повысить уровень безопасности и гибкости методов.

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

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace LC_Console

{

class TimePeriod

{

private double seconds;

// Свойство

public double Hours

{

get { return seconds / 3600; }

set { seconds = value * 3600; }

}

}

 

class Program

{

static void Main()

{

TimePeriod t = new TimePeriod();

 

// При передаче значения свойству будет вызвано "set" (24 * 3600)

t.Hours = 24;

// Извлечение значения из свойства вызывает "get" (24 * 3600 / 3600)

Console.WriteLine("Время в часах: " + t.Hours);

Console.WriteLine("Для продолжение нажмите любую клавишу... ");

Console.ReadKey();

}

}

 

}

/* Выведет:

* Время в часах: 24

* Для продолжение нажмите любую клавишу...

*/

 

Общие сведения о свойствах:

  • Свойства позволяют классу предоставлять общий способ получения и задания значений, скрывая при этом код реализации или проверки.
  • Метод доступа свойства get используется для возврата значения свойства, а метод доступа set используется для назначения нового значения. Эти методы доступа могут иметь различные уровни доступа. Дополнительные сведения можно получить в разделе Ограничение доступности методов доступа (Руководство по программированию на C#) (http://msdn.microsoft.com/ru-ru/library/75e8y5dd.aspx).
  • Ключевое слово value используется для определения значения, присваиваемого методом доступа set.
  • Свойства, которые не реализуют метод доступа set, доступны только для чтения.
  • Для простых свойств, не требующих пользовательского кода метода доступа, рассмотрите возможность использования автоматически реализуемых свойств.

 



Поделиться:


Последнее изменение этой страницы: 2016-08-15; просмотров: 460; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.218.218.230 (0.094 с.)