Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Вызов метода. Семантика

О соответствии списков формальных и фактических аргументов

Между списком формальных и списком фактических аргументов должно выполняться определенное соответствие по числу, порядку следования, типу и статусу аргументов. Если в первом списке n формальных аргументов, то фактических аргументов должно быть не меньше n (соответствие по числу). Каждому i -му формальному аргументу (для всех i = 1…n-1) ставится в соответствие i -й фактический аргумент. Последнему формальному аргументу, при условии, что он объявлен с ключевым словом params, ставятся в соответствие все оставшиеся фактические аргументы (соответствие по порядку). Если формальный аргумент объявлен с ключевым словом ref или out, то фактический аргумент должен сопровождаться таким же ключевым словом в точке вызова (соответствие по статусу).

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

Если формальный аргумент объявлен с типом T, то выражение, задающее фактический аргумент, должно быть согласовано по типу с типом T: допускает преобразование к типу T, совпадает c типом T или является его потомком (соответствие по типу).

Если формальный аргумент является выходным - объявлен с ключевым словом ref или out, - то соответствующий фактический аргумент не может быть выражением, поскольку используется в левой части оператора присваивания; следовательно, он должен быть именем, которому можно присвоить значение.

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

Для простоты понимания семантики вызова можно полагать, что в точке вызова создается блок, соответствующий телу метода (в реальности все значительно эффективнее). В этом блоке происходит замена имен формальных аргументов фактическими аргументами. Для выходных аргументов, для которых фактические аргументы также являются именами, эта замена или передача аргументов осуществляется по ссылке, то есть заменяет формальный аргумент ссылкой на реально существующий объект, заданный фактическим аргументом. Чуть более сложную семантику имеет вызов по значению, применяемый к формальным аргументам, которые объявлены без ключевых слов ref и out. При вычислении выражений, заданных такими фактическими аргументами, их значения присваиваются специально создаваемым переменным, локализованным в теле исполняемого блока. Имена этих локализованных переменных и подставляются вместо имен формальных аргументов. Понятно, что тип локализованных переменных определяется типом соответствующего формального аргумента. Понятно также, что семантика замены формальных аргументов фактическими - это, по сути, семантика оператора присваивания.

Семантика присваивания рассматривалась ранее.

Каково следствие семантики вызова по значению? Если вы забыли указать ключевое слово ref или out для аргумента, фактически являющегося выходным, то к нему будет применяться вызов по значению. Даже если в теле метода происходит изменение значения этого аргумента, то оно действует только на время выполнения тела метода. Как только метод заканчивает свою работу (завершается блок), все локальные переменные (в том числе, созданные для замены формальных аргументов) оканчивают свое существование, так что изменения не затронут фактических аргументов и они сохранят свои значения, бывшие у них до вызова. Отсюда вывод: все выходные аргументы, значения которых предполагается изменить в процессе работы, должны иметь ключевое слово ref или out. Еще один важный вывод: ключевым словом ref полезно иногда снабжать и входные аргументы. Если известно, что фактический аргумент будет всегда представлен именем, а не сложным выражением, то в целях экономии памяти разумно для таких аргументов применять семантику вызова по ссылке. В этом случае не будет создаваться копия аргумента - это экономит память и время, что может быть важно при работе со сложными структурами.

Говоря о семантике вызова по ссылке и по значению, следует сделать одно важное уточнение. В объектном программировании, каковым является и программирование на C#, основную роль играют ссылочные типы - мы работаем с классами и объектами. Когда методу передается объект ссылочного типа, то все поля этого объекта могут меняться в методе самым беззастенчивым образом. И это несмотря на то, что объект формально не является выходным, не имеет ключевых слов ref или out, использует семантику вызова по значению. Сама ссылка на объект, как и положено, остается неизменной, но состояние объекта, его поля могут полностью обновиться. Такая ситуация типична и представляет один из основных способов изменения состояния объектов. Именно поэтому ref или out не часто появляются при описании аргументов метода.

9. Что нужно знать о методах?

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

Почему у методов мало аргументов?

Методы класса имеют значительно меньше аргументов, чем процедуры и функции в классическом процедурном стиле программирования, когда не используется концепция классов. За счет чего происходит уменьшение числа аргументов у методов? Ведь аргументы играют важную роль: они передают методу информацию, нужную ему для работы, и возвращают информацию - результаты работы метода - программе, вызвавшей его.

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

Поля класса или функции без аргументов?

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

В языке C#, когда мы хотим получить длину строки, то пишем s.Length, точно зная, что Length - это поле, а не метод класса String. Если бы по каким-либо причинам разработчики класса String решили изменить реализацию и заменить поле Length соответствующей функцией, то ее вызов имел бы вид s.Length().

Пример: две версии класса Account

Проиллюстрируем рассмотренные выше вопросы на примере проектирования классов Account и Account1, описывающих такую абстракцию данных, как банковский счет. Определим на этих данных две основные операции - занесение денег на счет и снятие денег. В первом варианте - классе Account - будем активно использовать поля класса. Помимо двух основных полей credit и debit, хранящих приход и расход счета, введем поле balance, которое задает текущее состояние счета, и два поля, связанных с последней выполняемой операцией. Поле sum будет хранить сумму денег текущей операции, а поле result - результат выполнения операции. Полей у класса много, и как следствие, у методов класса аргументов будет немного. Вот описание нашего класса:

/// <summary>

/// Класс Account определяет банковский счет. Простейший

/// вариант с возможностью трех операций: положить деньги

/// на счет, снять со счета, узнать баланс.Вариант с полями

/// </summary>

<== предыдущая лекция | следующая лекция ==>
Вызов метода. Синтаксис | Public class Account
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 513; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.013 сек.