Обработка исключительных ситуаций с помощью блоков try/catch/finally

Вопросы на экзамен по курсу “Визуальное программирование”, ПС-15-1

Обработка исключительных ситуаций с помощью блоков try/catch/finally

Оператор try содержит три части:

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

• один или несколько обработчиков исключений — блоков catch, в которых описывается, как обрабатываются ошибки различных типов;

блок завершенияfinally выполняется независимо от того, возниклаошибкав контролируемом блоке или нет.

Синтаксис оператора try:

tryблок [ блоки catch ] [ блок finally ]

Отсутствовать могут либо блоки catch, либо блок finally, но не оба одновременно.

Рассмотрим, каким образом реализуется обработка исключительных ситуаций.

1. Обработка исключения начинается с появления ошибки. Функция или операция, в которой возникла ошибка, генерирует исключение. Как правило, исключение генерируется не непосредственно в блоке try, а в функциях, прямо или косвенно в него вложенных.

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

3. Выполняется блок finally, если он присутствует (этот блок выполняется и в том случае, если ошибка не возникла).

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

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

Синтаксис обработчиков напоминает определение функции с одним параметром — типом исключения. Существуют три формы записи:

catch( тип имя ) { ... / * тело обработчика * / }

catch( тип ) { ... / * тело обработчика * / }

catch { ... / * тело обработчика * / }

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

Вторая форма не предполагает использования информации об исключении, играет роль только его тип.

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

Пример:

try {

// Контролируемый блок

}

catch( OverflowException e ) {

. . . // Обработка исключений класса OverflowException (переполнение)

}

catch( IndexOutOfRangeExceptione ) {

... //Обработка исключений класса IndexOutOfRangeException (индекс вне границ массива)

}

catch {

// Обработка всех остальных исключений

}

Если исключение в контролируемом блоке не возникло, все обработчики пропускаются.В любом случае, произошло исключение или нет, управление передается в блок завершения finally (если он существует), а затем — первому оператору, находящемуся непосредственно за оператором try. В завершающем блоке обычно записываются операторы, которые необходимо выполнить независимо от того, возникло исключение или нет, например, закрытие файлов, с которыми выполнялась работа в контролируемом блоке, или вывод информации.

Конструкторы класса и ключевое слово this

Ключевое слово this

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

В явном виде параметр this применяется для того, чтобы возвратить из метода ссылку на вызвавший объект, а также для идентификации поля в случае, если его имя совпадает с именем параметра метода, например:

Class Example

{

int a;

public void Changea( int a )

{

this.a += a;

}

}

Конструкторы класса

Конструктор предназначен для инициализации объекта. Он вызывается автоматически при создании объекта класса с помощью операции new. Имя конструктора совпадает с именем класса. Ниже перечислены свойства конструкторов:

· Конструктор не возвращает значение, даже типа void.

· Класс может иметь несколько конструкторов с разными параметрами для разных видов инициализации.

· Если программист не указал ни одного конструктора иди какие-то поля небыли инициализированы, полям значимых типов присваивается нуль, а полямссылочных типов — значение null.

· Конструктор, вызываемый без параметров, называется конструктором по умолчанию.

Если же при создании объектов требуется присваивать полю разные значения, это следует делать в конструкторе. Часто бывает удобно задать в классе несколько конструкторов, чтобы обеспечить возможность инициализации объектов разными способами.

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

class Demo

{

public Demo( int a ) // конструктор 1

{

this.a = a;

}

public Demo( int a, double у ) : this( a ) // вызовконструктора 1

{

this.y = у:

}

}

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

***

Существует второй тип конструкторов — статические конструкторы, или конструкторы класса. Конструктор экземпляра инициализирует данные экземпляра, конструктор класса — данные класса.

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

экземпляры таких объектов не имеет смысла.

Существует возможность описывать статический класс, то есть класс

с модификатором static. Экземпляры такого класса создавать запрещено, и кроме того, от него запрещено наследовать.

Все элементы такого класса должны явным образом объявляться с модификатором static (константы и вложенные типы классифицируются как статические элементы автоматически). Конструктор экземпляра

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

Примеры применения пользовательских шаблонов форматирования

Число Шаблон Вид

1,243 00.00 01,24

1,243 #.## 1,24

0,1 00.00 00,10

0,1 #.## ,1

Пользовательский шаблон может также содержать текст, который в общем случае

заключается в апострофы.

Поля и методы класса

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

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

[ атрибуты ] [ спецификаторы ] [ const ] тип имя [ = начальное_значение ]

· new Новое описание поля, скрывающее унаследованный элемент класса.

· publiс Доступ к элементу не ограничен.

· protected Доступ только из данного и производных классов.

· internal Доступ только из данной сборки.

· protectedinternalДоступ только из данного и производных классов и из данной сборки.

· privateДоступ только из данного класса

· staticОдно поле для всех экземпляров класса

· readonlyПоле доступно только для чтения

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

MyClass.a = 15;

Все поля сначала автоматически инициализируются нулем соответствующего типа (например, полям типа int присваивается 0, а ссылкам на объекты — значение null). После этого полю присваивается значение, заданное при его явной инициализации. Задание начальных значений для статических полей выполняется при инициализации класса, а обычных — при создании экземпляра.

Поля со спецификатором readonly предназначены только для чтения. Установить значение такого поля можно либо при его описании, либо в конструкторе.

Методы

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

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

Синтаксис метода:

[ атрибуты ] [ спецификаторы ] тип имя метода ( [ параметры ] )

тело_метода

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

При описании методов можно использовать спецификаторы имеющие тот же смысл, что и для полей, а также спецификаторы virtual, sealed, override, abstract и extern, которые будут рассмотрены по мер необходимости.

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

Статические (static) методы, или методы класса, можно вызывать, не создавая экземпляр объекта.

publicint GetHello()

{

return“Hello World! ”;

}

Тип определяет, значение какого типа вычисляется с помощью метода. Часто употребляется термин «метод возвращает значение», поскольку после выполнения метода происходит возврат в то место вызывающей функции, откуда был вызван метод, и передача туда значения выражения, записанного в операторе return. Если метод имеет тип void, то он не возвращает никакого значения, оператор returnотсутствует.

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

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

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

public static double Sin( double a );

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

Метод, описанный со спецификатором static, должен обращаться только к статическим полям класса. Обратите внимание на то, что статический методвызывается через имя класса, а обычный— через имя экземпляра.

В С# для обмена данными между вызывающей и вызываемой функциями предусмотрено

четыре типа параметров:

• параметры-значения;

• параметры-ссылки — описываются с-помошью ключевого слова ref;

• выходные параметры — описываются с помощью ключевого слова out;

• параметры-массивы — описываются с помощью ключевого слова params.

Параметр-значение описывается в заголовке метода следующим образом:

Тип имя

Пример заголовка метода, имеющего один параметр-значение целого типа:

VoidP( intx )

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

Признаком параметра-ссылки является ключевое слово ref перед описанием параметра:

Refтипимя

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

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

Цикл с предусловием while

Формат оператора прост:

Цикл с постусловием do

Имеет вид

do оператор while выражение;

Сначала выполняется простой или составной оператор, образующий тело цикла, а затем вычисляется выражение (оно должно иметь тип bool). Если выражение истинно, тело цикла выполняется еще раз и проверка повторяется. Цикл завершается, когда выражение станет равным false или в теле цикла будет выполнен какой-либо оператор передачи управления.

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

Пример самостоятельно.

Цикл с параметром for

Цикл с параметром имеет следующий формат:

for ( инициализация; выражение; модификации ) оператор;

Инициализация служит для объявления величин, используемых в цикле, и присвоения им начальных значений. В этой части можно записать несколько операторов, разделенных запятой, например:

for ( int i - 0, j - 20; ...

int k, m;

for ( k - 1. m - 0: ...

Областью действия переменных, объявленных в части инициализации цикла, является цикл. Инициализация выполняется один раз в начале исполнения цикла. Выражение типа bool определяет условие выполнения цикла: если его результатравен true, цикл выполняется. Цикл с параметром реализован как цикл с предусловием. Модификации выполняются после каждой итерации цикла и служат обычно для

изменения параметров цикла.

Простой или составной оператор представляет собой тело цикла. Любая из частей оператора for может быть опущена (но точки с запятой надо оставить на своих местах!).

Пример самостоятельно.

Оператор foreach

Оператор foreach применяется для перебора элементов вспециальным образом организованной группе данных. Массив является именно такой группой. Удобство этого вида цикла заключается в том, что нам не требуется определять количество элементов в группе и выполнять их перебор по индексу: мы просто указываем на необходимость перебрать все элементы группы. Синтаксис оператора:

foreach ( тип имя in выражение ) тело_цикла

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

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

Пример самостоятельно.

Тело класса

Обратите внимание на то, что слово «предки» присутствует в описании класса во множественном числе, хотя класс может иметь только одного предка. Причина в том, что класс наряду с единственным предком может наследовать от интерфейсов — специального вида классов, не имеющих реализации.

Конструкторы не наследуются, поэтому производный класс должен иметь собственные конструкторы. Порядок вызова конструкторов определяется приведенными далее правилами:

· Если в конструкторе производного класса явный вызов конструктора базового класса отсутствует, автоматически вызывается конструктор базового класса без параметров.

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

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

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

Возможность доступа к методу базового класса из метода производного

класса сохраняется. Для этого перед вызовом метода указывается все то же волшебное слово base.

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

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

• объект, в который во время выполнения программы заносятся ссылки на объекты разных классов иерархии;

• контейнер, в котором хранятся объекты разных классов, относящиеся кодной иерархии;

• метод, в который могут передаваться объекты разных классов иерархии;

• метод, из которого в зависимости от типа вызвавшего его объекта вызываются соответствующие методы.

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

Ключевое слово sealedв заголовке класса запрещает наследовать его.

7. Описать операторы ветвления с примерами их применения

Условный оператор if

Условный оператор i f используется для разветвления процесса вычислений на два направления.

       
  Обработка исключительных ситуаций с помощью блоков try/catch/finally - student2.ru
 
    Обработка исключительных ситуаций с помощью блоков try/catch/finally - student2.ru

Формат оператора:

i f ( логическое_выражение ) оператор_1; [ else оператор_2: ]

Сначала вычисляется логическое выражение. Если оно имеет значение true, выполняется первый оператор, иначе — второй. После этого управление передается на оператор, следующий за условным. Ветвь else может отсутствовать.

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

Примеры условных операторов:

if ( а < 0 ) b = 1; //1

i f ( а < b && ( а > d И а == 0 ) ) b++; else { b *= а: а = 0; }//2

i f ( a < b ) i f ( a < c ) m - a; elsem = c;

else if ( b <с ) m - b: else m = c; //3

i f ( b > a ) max = b; else max = a; //4

В примере 1 отсутствует ветвь else. Подобная конструкция реализует пропуск Оператора, поскольку присваивание либо выполняется, либо пропускается в зависимости от выполнения условия.

Если требуется проверить несколько условий, их объединяют знаками логических условных операций. Например, выражение в примере 2 будет истинно в том случае, если выполнится одновременно условие а < b и одно из условий в скобках. Если опустить внутренние скобки, будет выполнено сначала логическое И, а потом —ИЛИ.

Оператор в примере 3 вычисляет наибольшее значение из трех переменных. Обратите внимание на то, что компилятор относит часть else к ближайшему ключевому слову if.

Конструкции, подобные оператору в примере 4 (вычисляется наибольшее значение из двух переменных), проще и нагляднее записывать в виде условной операции, в данном случае следующей:

max = b > а ? b : a;

Следует избегать проверки вещественных величин на равенство, вместо этого лучше сравнивать модуль их разности с некоторым малым числом.

Оператор выбора switch

Оператор switch (переключатель) предназначен для разветвления процесса вычислений на несколько направлений.

 
  Обработка исключительных ситуаций с помощью блоков try/catch/finally - student2.ru

Обработка исключительных ситуаций с помощью блоков try/catch/finally - student2.ru Обработка исключительных ситуаций с помощью блоков try/catch/finally - student2.ru .

case n
.

 
  Обработка исключительных ситуаций с помощью блоков try/catch/finally - student2.ru

Формат оператора:

switch ( выражение ){

case константное_выражение_1: [ список_операторов_1 ]

case константное_выражение_2: [ список_операторов_2 ]

case константное_выражение_п: [ списокоператоровп ]

[ default: операторы ]

}

Выполнение оператора начинается с вычисления выражения. Тип выражения

чаще всего целочисленный (включая char) или строковый1. Затем управление передается первому оператору из списка, помеченному константным выражением, значение которого совпало с вычисленным.

Все константные выражения должны быть неявно приводимы к типу выражения в скобках. Если совпадения не произошло, выполняются операторы, расположенные после слова default (а при его отсутствии управление передается следующему за switch оператору).

Каждая ветвь переключателя должна заканчиваться явным оператором перехода, а именно оператором break, goto или return:

• оператор break выполняет выход из самого внутреннего из объемлющих его операторов switch, for, while и do;

• оператор goto выполняет переход на указанную после него метку, обычно это метка case одной из нижележащих ветвей оператора switch;

• оператор return выполняет выход из функции, в теле которой он записан.

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

Хотя наличие ветви default и не обязательно, рекомендуется всегда обрабатыватьслучай, когда значение выражения не совпадает ни с одной из констант. Это облегчает поиск ошибок при отладке программы.

Оператор switch предпочтительнее оператора i f в тех случаях, когда в программе требуется разветвить вычисления на количество направлений большее двух и выражение, по значению которого производится переход на ту или иную ветвь, не является вещественным. Часто это справедливо даже для двух ветвей, поскольку повышает наглядность программы.

System.Array

Содержит множество методов и свойств, например:

• Length – свойство, возвращает количество элементов массива;

• Clear – статический метод, присваивание всем элементам значения по умолчанию;

• Copy – статический метод, копирование заданного диапазона элементов одного массива в другой;

• Sort – статический метод, упорядочивает элементы одномерного массива.

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

Пример использование самостоятельно.

К статическим методам обращаемся через имя класса (такие как Sort, IndexOf, BinarySearch).

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

Имя_параметра.GetValue(i).

Прямоугольные массивы

Прямоугольный массив имеет более одного измерения. Чаще всего в программах используются двумерные массивы. Варианты описания двумерного массива:

тип[,] имя;

тип[,] имя = new тип [ разм_1, разн_2 ] ;

тип[,] имя = { списокинициализаторов }:

тип[,] имя = new тип [,] { списокинициализаторов };

тип[,] иня = new тип [ рази_1, разн_2 ] { списокинициализаторов };

Примеры описаний (один пример для каждого варианта описания):

int[ , ] a; // 1

int[ , ] b = new int[2. 3]: 111

int[ , ] c = { {1. 2. 3} , {4. 5. 6} }; // 3

int [ , ] с = new int [ , ] {{1. 2. 3}. {4, 5. 6}}: // 4

int [ , ] d = new int[2,3] {{1. 2. 3}. {4, 5. 6}};// 5

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

а[1 , 4] b[i, j] b[j , i]

Пример самостоятельно.

Ступенчатые массивы

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

Обработка исключительных ситуаций с помощью блоков try/catch/finally - student2.ru

Описание ступенчатого массива:

тип[][] имя;

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

int [ ][ ] a = newint[3][ ];

а[0] = new int[5];

а[1] = new int[3];

a[2] = new int[4];

Здесь а[0],а[1]иа[2] — это отдельные массивы, к которым можно обращаться по имени. Другой способ выделенияпамяти:

int [ ][ ] а = { new int[5]. new int[3]. new int[4] };

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

а[1][2] a[i][j] a[j][i]

В остальном использование ступенчатых массивов не отличается от использования прямоугольных. Невыровненные массивы удобно применять, например, дляработы с треугольными матрицами большого объема.

Public Stack()

Public Queue()

Public Queue (int capacity)

Перегрузка методов

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

Компилятор определяет, какой именно метод требуется вызвать, по типу фактических параметров. Этот процесс называется разрешением (resolution) перегрузки. Тип возвращаемого методом значения в разрешении не участвует. Механизм разрешения основан на достаточно сложном наборе правил, смысл которых сводится к тому, чтобы использовать метод с наиболее подходящими аргументами и выдать сообщение, если такой не найдется.

Если точного соответствия не найдено, выполняются неявные преобразования типов в соответствии с общими правилами, например, bool и char в int, floatв doubl е и т. п. Если преобразование невозможно, выдается сообщение об ошибке. Если соответствие на одном и том же этапе может быть получено более чемодним способом, выбирается «лучший» из вариантов, то есть вариант, содержащийменьшие количество и длину преобразований в соответствии с правилами.

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

Int max( int a. int b )

Int max( int a, ref int b )

Перегрузка методов является проявлением полиморфизма, одного из основных свойств ООП. Программисту гораздо удобнее помнить одно имя метода и использоватьего для работы с различными типами данных, а решение о том, какой вариант метода вызвать, возложить на компилятор. Этот принцип широко используетсяв классах библиотеки .NET. Например, в стандартном классе Console метод WriteLine перегружен 19 раз для вывода величин разных типов.

Примеры применения пользовательских шаблонов форматирования

Число Шаблон Вид

1,243 00.00 01,24

1,243 #.## 1,24

0,1 00.00 00,10

0,1 #.## ,1

Пользовательский шаблон может также содержать текст, который в общем случае

заключается в апострофы.

Возможности, предоставляемые классом string, широки, однако требование неизменности его объектов может оказаться неудобным. В этом случае для работы со строками применяется класс StringBuilder, определённый в пространствеимен System.Text и позволяющий изменять значение своих экземпляров. При создании экземпляра обязательно использовать операцию new и конструктор,например:

StringBuilder a = new StringBuilder();

StringBuilder b - new StringBuilder( "qwerty" );

StringBuilder с = new StringBuilder( 100 );

StringBuilder d = new StringBuilder( "qwerty". 100');

StringBuilder e = new StringBuilder( "qwerty", 1, 3, 100);

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

Если применяется конструктор без параметров (оператор 1), создается пустая строка размера, заданного по умолчанию (16 байт). Другие виды конструкторов задают объем памяти, выделяемой строке, и/или ее начальное значение. Например, в операторе 5 объект инициализируется подстрокой длиной 3 символа, начиная с первого (подстрока "wer").

Элементы класса:

• Append – метод, добавление в конец строки;

• Capacity – свойство, получение или установка емкости буфера;

• Insert – метод, вставка подстроки в заданную позицию;

• Length – свойство, длинна строки;

• ToString – метод, преобразование в строку типа string.

using System;

using System.Text;

namespace ConsoleApplicationl

{ class Class1

{ static void Main()

{

Console.Write( "Введитезарплату: " );

double salary = double.Parse( Console.ReadLine() ):

StringBuilder a - new StringBuilder();

a.Append( "зарплата " );

a.AppendFormat( "{0, 6:C} - вгод {1, б:С}",

salary, salary * 12 );

Console.WriteLine( a );

a.Replace( "p.", "тыс.$" );

Console.WriteLine( "А лучше было бы: " + a );

}

}

}

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

Sealed class Spirit

{

}

/ / class Monster : Spirit { ... } ошибка!

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

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

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

При использовании в качестве модификатора объявления ключевое слово new явным образом скрывает члены, унаследованные от базового класса.При скрытии унаследованного члена его производная версия заменяет версию базового класса.Хотя члены можно скрывать без использования модификатора new, в этом случае появляется предупреждение компилятора.При использовании new для явного скрытия члена, предупреждение не появляется.

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

Например:

Publicclass BaseC

{

Publicclass NestedC

{

publicint x = 200;

publicint y;

}

}

Newpublicclass NestedC

{

publicint x = 100;

publicint y;

publicint z;

}

Тут класс DerivedCимеет вложенный класс NestedC, который скрывает с помощью модификатора newявным образом аналогичный класс класса-предка BaseC.

Class Program

{

static void MainO {

SI0::Stream s = new MIO::EmptyStream(); // использованиепсевдонимов

}

}

Есть оператор using1 со следующим синтаксисом:

using ( выделение_ресурса ) оператор

Под ресурсом здесь понимается объект, который реализует интерфейс System.IDisposable, включающий метод Dispose. Код, использующий ресурс, вызовом этогометода сигнализирует о том, что ресурс больше не требуется. Если метод Disposeне был вызван, освобождение ресурса выполняется в процессе сборки мусора.Оператор using неявным образом вызывает метод Dispose в случае успешногосоздания и использования объекта.

using ( Pen pen - new Pen( Color.Red ) )

{

g.DrawLine( pen, 0, 0. 200, 100 );

g.DrawEllipse( pen, new Rectangle(50, 50, 100, 150) );

}

Common Type Specification

CommonTypeSystem - часть .NET Framework, формальная спецификация, определяющая, как какой-либо тип (класс, интерфейс, структура, встроенный тип данных) должен быть определён для его правильного выполнения средой .NET. Кроме того, данный стандарт определяет, как определения типов и специальные значения типов представлены в компьютерной памяти. Целью разработки CTS было обеспечение возможности программам, написанным на различных языках программирования, легко обмениваться информацией. Как это принято в языках программирования, тип может быть описан как определение набора допустимых значений (например, «все целые от 0 до 10») и допустимых операций над этими значениями (например, сложение и вычитание).

Функции Common Type System

· Формирует фреймворк, способствующий межъязыковой интеграции, безопасности типов, а также высокой производительности исполнения кода.

· Обеспечивает объектно-ориентированную модель, поддерживающую полную реализацию множества языков программирования.

· Определяет правила, которым должны следовать языки, что в том <

Наши рекомендации