Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шпоры по языкам программирования.docx
Скачиваний:
4
Добавлен:
18.09.2019
Размер:
156.2 Кб
Скачать

Вопрос 23. Синтаксис класса.

синтаксис описания класса:

[атрибуты][модификаторы]class имя_класса[:список_родителей]

{тело_класса}

Возможными модификаторами в объявлении класса

могут быть модификаторы new, abstract, sealed, о которых подробно будет говориться при

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

public class Rational {тело_класса}

В теле класса могут быть объявлены:

константы;

поля;

конструкторы и деструкторы;

методы;

события;

делегаты;

классы (структуры, интерфейсы, перечисления).

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

Как уже упоминалось, внутренние классы обычно имеют модификатор доступа, отличный от public. Основу любого класса составляют его конструкторы, поля и методы.

Вопрос№24.Поля класса. Доступ к полям

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

Доступ к полям.

Каждое поле имеет модификатор доступа, принимающий одно из четырех значений: public, private,protected, internal. Атрибутом доступа по умолчанию является атрибут private. Независимо от значения атрибута доступа, все поля доступны для всех методов класса. Они являются для методов класса глобальной информацией, с которой работают все методы, извлекая из полей нужные им данные и изменяя их значения в ходе работы. Если поля доступны только для методов класса, то они имеют атрибут доступа private, который можно опускать. Такие поля считаются закрытыми, но часто желательно, чтобы некоторые из них были доступны в более широком контексте. Если некоторые поля класса A должны быть доступны для методов класса B, являющегося потомком класса A, то эти поля следует снабдить атрибутом protected. Такие поля называются защищенными. Если некоторые поля должны быть доступны для методов классов B1, B2 и так далее, дружественных по отношению к классу A, то эти поля следует снабдить атрибутом internal, а все дружественные классы B поместить в один проект (assembly). Такие поля называются дружественными. Наконец, если некоторые поля должны быть доступны для методов любого класса B, которому доступен сам класс A, то эти поля следует снабдить атрибутом public. Такие поля называются общедоступными или открытыми.

Вопрос№25.Развернутые и ссылочные типы

Рассмотрим объявление объекта класса T с инициализацией:T x = new T();В памяти создается объект типа T, основанного на классе T,и сущность x связывается с этим объектом. Сущность, не прошедшая инициализацию (явную или неявную), не связана ни с одним объектом, а потому не может использоваться в вычислениях - у нее нет полей, хранящих значения, она не может вызывать методы класса. Объектам нужна память, чтобы с ними можно было работать. Есть две классические стратегии выделения памяти и связывания объекта, создаваемого в памяти, и сущности, объявленной в тексте.Определение 1. Класс T относится к развернутому типу, если память отводится сущности x; объект разворачивается на памяти, жестко связанной с сущностью. Определение 2. Класс T относится к ссылочному типу, если память отводится объекту; сущность x является ссылкой на объект.Для развернутого типа характерно то, что каждая сущность ни с кем не разделяет свою память;сущность жестко связывается со своим объектом. В этом случае сущность и объект можно и не различать, они становятся неделимым понятием. Для ссылочных типов ситуация иная – несколько сущностей могут ссылаться на один и тот же объект. Такие сущности разделяют память и являются разными именами одного объекта. Полезно понимать разницу между сущностью, заданной ссылкой, и объектом, на который в текущий момент указывает ссылка.Развернутые и ссылочные типы порождают две различные семантики присваивания – развернутое присваивание и ссылочное присваивание. Рассмотрим присваивание:y = x;Когда сущность y и выражение x принадлежат развернутому типу, то при присваивании изменяется объект. Значения полей объекта, связанного с сущностью y, изменяются, получая значения полей объекта, связанного с x. Когда сущность y и выражение x принадлежат ссылочному типу, то изменяется ссылка, но не объект. Ссылка y получает значение ссылки x, и обе они после присваивания указывают на один и тот же объект.у класса нет модификатора, позволяющего задать развернутый или ссылочный тип. к значимым типам относятся все встроенные арифметические типы, булев тип, структуры; к ссылочным типам - массивы, строки, классы. Так можно ли в C# спроектировать свой собственный класс так, чтобы он относился к значимым типам? Ответ на это вопрос положительный, хотя и с рядом оговорок. Для того чтобы класс отнести к значимым типам, его нужно реализовать как структуру.

Вопрос№26..Классы и структуры

Структура - это частный случай класса.если необходимо отнести класс к развернутому типу, делайте его структурой;если у класса число полей относительно невелико, а число возможных объектов относительно велико, делайте его структурой. В этом случае память объектам будет отводиться в стеке, не будут создаваться лишние ссылки, что позволит повысить эффективность работы;в остальных случаях проектируйте настоящие классы.Поскольку на структуры накладываются дополнительные ограничения, то может возникнуть необходимость в компромиссе - согласиться с ограничениями и использовать структуру либо пожертвовать развернутостью и эффективностью и работать с настоящим классом.Синтаксис объявления структуры аналогичен синтаксису объявления класса:[атрибуты][модификаторы]struct имя_структуры[:список_интерфейсов]{тело_структуры}ключевое слово class изменено на слово struct;список родителей, который для классов, наряду с именами интерфейсов, мог включать имя

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

(класс или структура). Заметьте, структура может наследовать интерфейсы;для структур неприменимы модификаторы abstract и sealed. Причиной является отсутствие механизма наследования.Все, что может быть вложено в тело класса, может быть вложено и в тело структуры: поля, методы,конструкторы и прочее, включая классы и интерфейсы.Аналогично классу, структура может иметь статические и не статические поля и методы, может иметь несколько конструкторов, в том числе статические и закрытые конструкторы. Для структур можно создавать собственные константы, используя поля с атрибутом readonly и статический конструктор.Структуры похожи на классы по своему описанию и ведут себя сходным образом, хотя и имеют существенные различия в семантике присваивания.У структуры не может быть наследников. У структуры не может быть задан родительский класс или родительская структура. всякая структура является наследником класса Object,наследуя все свойства и методы этого класса. Структура может быть наследником одного или нескольких интерфейсов, реализуя методы этих интерфейсов.Пусть T - структура, и дано объявление без инициализации - Tx. Это объявление корректно, в результате будет создан объект без явного вызова операции new. Сущности x будет отведена память, и на этой памяти будет развернут объект. Но поля объекта не будут инициализированы и, следовательно, не будут доступны для использования в вычислениях. Об этих особенностях подробно говорилось при рассмотрении значимых типов. В этом отношении все, что верно для типа int, верно и для всехструктур.Если при объявлении класса его поля можно инициализировать, что найдет отражение при работе конструктора класса, то поля структуры не могут быть инициализированы.Конструктор по умолчанию у структур имеется, при его вызове поля инициализируются значениями по умолчанию. Этот конструктор нельзя заменить, создав собственный конструктор без аргументов. В конструкторе нельзя вызывать методы класса. Поля структуры должны быть проинициализированы до вызова методов.

Вопрос№27.Отношения между классами

Каждый класс, как не раз отмечалось, играет две роли: он является модулем – архитектурной единицей, и он имеет содержательный смысл, определяя некоторый тип данных. Но классы программной системы - это ансамбль, в котором классы, играя свои роли, не являются независимыми -все они находятся в определенных отношениях друг с другом. Два основных типа отношений между классами определены в ОО-системах. Первое отношение "клиенты и поставщики", называется часто клиентским отношением или отношением вложенности (встраивания). Второе отношение "родители и наследники" называется отношением наследования.Определение 1. Классы А и В находятся в отношении "клиент-поставщик", если одним из полей класса В является объект класса А. Класс А называется поставщиком класса В, класс В называется клиентом класса А.Определение 2. Классы А и В находятся в отношении "родитель - наследник", если при объявлении класса В класс А указан в качестве родительского класса. Класс А называется родителем класса В,класс В называется наследником класса А.Оба отношения - наследования и вложенности - являются транзитивными. Если В - клиент А и С -клиент В, то отсюда следует, что С - клиент А. Если В - наследник А и С - наследник В, то отсюда следует, что С - наследник А.Прямые клиенты и поставщики, прямые родители и наследники относятся к соответствующему уровню.Прямые классы-наследники часто называются сыновними или дочерними классами. Непрямые родители называются предками, а их непрямые наследники - потомками.Замечу, что цепочки вложенности и наследования могут быть достаточно длинными. Например, библиотечные классы, составляющие систему Microsoft Office, полностью построены на отношении вложенности. При программной работе с объектами Word можно начать с объекта, задающего приложение Word, и добраться до объекта, задающего отдельный символ в некотором слове некоторого предложения одного из открытых документов Word. Для выбора нужного объекта можно задать такую цепочку: приложение Word - коллекция документов - документ -область документа - коллекция абзацев - абзац - коллекция предложений -предложение – коллекция слов - слово - коллекция символов - символ. В этой цепочке каждому понятию соответствует класс библиотеки Microsoft Office, где каждая пара соседствующих классов связана отношением "поставщик-клиент".Классы библиотеки FCL связаны как отношением вложенности, так и отношением наследования.Длинные цепочки наследования достаточно характерны для классов этой библиотеки.При проектировании классов часто возникает вопрос, какое же отношение между классами нужно построить. Рассмотрим совсем простой пример двух классов - Square и Rectangle, описывающих квадраты и прямоугольники. Наверное, понятно, что эти классы следует связать скорее отношением наследования, чем вложенности; менее понятным остается вопрос, а какой из этих двух классов следует сделать родительским. Еще один пример двух классов - Car и Person, описывающих автомобиль и персону. Найти правильные ответы на эти вопросы проектирования классов помогает понимание того, что отношение"клиент-поставщик" задает отношение "имеет" ("has"), а отношение наследования задает отношение"является"("isa"). В случае классов Square и Rectangle понятно, что каждый объект квадрат"является" прямоугольником, поэтому между этими классами имеет место отношение наследования, и родительским классом является класс Rectangle, а класс Square является его потомком.В случае автомобилей, персон и владельцев авто также понятно, что владелец "имеет" автомобиль и

"является" персоной. Поэтому класс Person_of_Car является клиентом класса Car и наследником класса Person.

Вопрос№28.Процедуры и функции - методы класса

Процедуры и функции связываются с классом, они обеспечивают функциональность данных класса и называются методами класса. Главную роль в программной системе играют данные, а функции лишь служат данным.В языке C# нет специальных ключевых слов - procedure и function, но присутствуют сами эти понятия. Синтаксис объявления метода позволяет однозначно определить, чем является метод -процедурой или функцией.Прежнюю роль библиотек процедур и функций теперь играют библиотеки классов. Библиотека классов FCL, доступная в языке C#, существенно расширяет возможности языка.Функция отличается от процедуры двумя собенностями:всегда вычисляет некоторое значение, возвращаемое в качестве результата функции;вызывается в выражениях.Процедура C# имеет свои особенности:возвращает формальный результат void, указывающий на отсутствие результата;вызов процедуры является оператором языка;имеет входные и выходные аргументы, причем выходных аргументов - ее результатов – может быть достаточно много.Если допускать функции с побочным эффектом, то любую процедуру можно записать в виде функции. В языке С - дедушке C# - так и сделали, оставив только функции. Однако значительно удобнее иметь обе формы реализации метода: и процедуры, и функции. Обычно метод предпочитают реализовать в виде функции тогда, когда он имеет один выходной аргумент,рассматриваемый как результат вычисления значения функции. Возможность вызова функций в выражениях также влияет на выбор в пользу реализации метода в виде функции. В других случаях метод реализуют в виде процедуры.Синтаксически в описании метода различают две части - описание заголовка и описание тела метода:заголовок_метода тело_метода.Рассмотрим синтаксис заголовка метода:[атрибуты][модификаторы]{void| тип_результата_функции} имя_метода([список_формальных_аргументов])Имя метода и список формальных аргументов составляют сигнатуру метода. Заметьте, в сигнатуру не входят имена формальных аргументов - здесь важны типы аргументов. В сигнатуру не входит и тип возвращаемого результата.Квадратные скобки показывают, что атрибуты и модификаторы могут быть опущены при описании метода. Подробное их рассмотрение будет дано в лекциях, посвященных описанию классов. Сейчас же упомяну только об одном из модификаторов – модификаторе доступа. У него четыре возможных значения, из которых пока рассмотрим только два - public и private. Модификатор public показывает, что метод открыт и доступен для вызова клиентами и потомками класса. Модификатор private говорит, что метод предназначен для внутреннего использования в классе и доступен для вызова только в теле методов самого класса. Заметьте, если модификатор доступа опущен, то по умолчанию предполагается, что он имеет значение private и метод является закрытым для клиентов и потомков класса.Обязательным при описании заголовка является указание типа результата, имени метода и круглых скобок, наличие которых необходимо и в том случае, если сам список формальных аргументов отсутствует. Формально тип результата метода указывается всегда, но значение void однозначно определяет, что метод реализуется процедурой. Тип результата, отличный от void, указывает на функцию. Вот несколько простейших примеров описания методов:void A() {...};int B(){...};public void C(){...}; Методы A и B являются закрытыми, а метод С - открыт. Методы A и С реализованы процедурами, а метод B - функцией, возвращающей целое значение. В классе можно объявить статический конструктор с атрибутом static. Он вызывается автоматически -его не нужно вызывать стандартным образом. Точный момент вызова не определен, но гарантируется, что вызов произойдет до создания первого объекта класса. Такой конструктор может выполнять некоторую предварительную работу, которую нужно выполнить один раз, например, связаться с базой

данных, заполнить значения статических полей класса, создать константы класса, выполнить другие подобные действия. Статический конструктор, вызываемый автоматически, не должен иметь модификаторов доступа. Вот пример объявления такого конструктора в классе Person: static Person(){ Console.WriteLine("Выполняется статический конструктор!");}В нашей тестирующей процедуре, работающей с объектами класса Person, этот конструктор вызывается первым, и первым появляется сообщение этого конструктора.объекты создаются динамически в процессе выполнения программы- для создания объекта всегда вызывается тот или иной конструктор класса.

Вопрос№29.Деструкторы класса

Если задача создания объектов полностью возлагается на программиста, то задача удаления объектов,после того, как они стали не нужными, в Visual Studio .Net снята с программиста и возложена на соответствующий инструментарий - сборщик мусора. Так же, как и статический конструктор, деструктор класса, если он есть, вызывается автоматически в процессе сборки мусора. Его роль - в освобождении ресурсов, например, файлов, открытых объектом.Деструктор C# фактически является финализатором (finalizer), с которыми мы еще встретимся приобсуждении исключительных ситуаций. Приведу формальное описание деструктора класса Person:Person(){ //Код деструктора}Имя деструктора строится из имени класса с предшествующим ему символом ~ (тильда). у деструктора не указывается модификатор доступа.Конструкторы класса.Конструктор - неотъемлемый компонент класса. Нет классов без конструкторов. Конструктор представляет собой специальный метод класса, позволяющий создавать объекты класса. Одна из синтаксических особенностей этого метода в том, что его имя должно совпадать с именем класса. Если программист не определяет конструктор класса, то к классу автоматически добавляется конструктор по умолчанию - конструктор без аргументов. Заметьте, что если программист сам создает один или несколько конструкторов, то автоматического добавления конструктора без аргументов не происходит.Как и когда происходит создание объектов? Чаще всего, при объявлении сущности в момент ее инициализации. Давайте обратимся к нашему последнему примеру и рассмотрим создание трех объектов класса Person:Person pers1 = new Person(), pers2 = new Person();Person pers3= new Person("Петрова");Сущности pers1, pers2 и pers3 класса Person объявляются с инициализацией, задаваемой унарной операцией new, которой в качестве аргумента передается конструктор класса Person. У класса может быть несколько конструкторов - это типичная практика,- отличающихся сигнатурой. В данном примере в первой строке вызывается конструктор без аргументов, во второй строке для сущности pers3 вызывается конструктор с одним аргументом типа string. Разберем в деталях процесс создания:первым делом для сущности pers создается ссылка, пока висячая, со значением null;затем в динамической памяти создается объект - структура данных с полями, определяемыми классом Person. Поля объекта инициализируются значениями по умолчанию: ссылочные поля -значением null, арифметические - нулями, строковые - пустой строкой. Эту работу выполняет конструктор по умолчанию, который, можно считать, всегда вызывается в начале процесса создания. Заметьте, если инициализируется переменная значимого типа, то все происходит аналогичным образом, за исключением того, что объект создается в стеке;если поля класса проинициализированы, как в нашем примере, то выполняется инициализация полей заданными значениями;если вызван конструктор с аргументами, то начинает выполняться тело этого конструктора. Как правило, при этом происходит инициализация отдельных полей класса значениями, переданными конструктору. Так, поле fam объекта pers3 получает значение "Петрова"; На заключительном этапе ссылка связывается с созданным объектом.Процесс создания объектов становится сложнее, когда речь идет об объектах, являющихся потомками некоторого класса. В этом случае, прежде чем создать сам объект, нужно вызвать конструктор,создающий родительский объект. Но об этом мы еще поговорим при изучении наследования.(Ключевое слово new используется в языке для двух разных целей. Во-первых, это имя операции, запускающей только что описанный процесс создания объекта. Во-вторых, это модификатор класса или метода. Роль new как модификатора будет выяснена при рассмотрении наследования.) в зависимости от контекста и создаваемого объекта, может требоваться различная инициализация его полей. Перегрузка конструкторов и обеспечивает решение этой задачи.Немного экзотики, связанной с конструкторами. Конструктор может быть объявлен с атрибутом private Понятно, что в этом случае внешний пользователь не может воспользоваться им для создания объектов.Но это могут делать методы класса, создавая объекты для собственных нужд со специальной инициализацией. Пример такого конструктора будет дан позже.

Вопрос№30. Интерфейсы

интерфейс- это частный случай класса. Интерфейс представляет собой полностью абстрактный класс, все методы которого абстрактны. От абстрактного класса интерфейс отличается некоторыми деталями в синтаксисе и поведении. Синтаксическое отличие состоит в том, что методы интерфейса объявляются без указания модификатора доступа. Отличие в поведении заключается в более жестких требованиях к потомкам.Класс, наследующий интерфейс, обязан полностью реализовать все методы интерфейса. В этом -отличие от класса, наследующего абстрактный класс, где потомок может реализовать лишь некоторые методы родительского абстрактного класса, оставаясь абстрактным классом. Но, конечно, не ради этих отличий были введены интерфейсы в язык C#. У них значительно более важная роль.Введение в язык частных случаев усложняет его и свидетельствует о некоторых изъянах, для преодоления которых и вводятся частные случаи. Например, введение структур в язык C# позволило определять классы как развернутые типы. Конечно, проще было бы ввести в объявление класса соответствующий модификатор, позволяющий любой класс объявлять развернутым. Интерфейсы позволяют частично справиться с таким существенным недостатком языка, как отсутствие множественного наследования классов. Хотя реализация множественного наследования встречается с рядом проблем, его отсутствие существенно снижает выразительную мощь языка. В языке C# полного множественного наследования классов нет. Чтобы частично сгладить этот пробел, допускается

множественное наследование интерфейсов. Обеспечить возможность классу иметь несколько родителей- один полноценный класс, а остальные в виде интерфейсов,- в этом и состоит основное назначение интерфейсов.Отметим одно важное назначение интерфейсов. Интерфейс позволяет описывать некоторые желательные свойства, которыми могут обладать объекты разных классов. В библиотеке FCL имеется большое число подобных интерфейсов, с некоторыми из них мы познакомимся в этой лекции. Все классы, допускающие сравнение своих объектов, обычно наследуют интерфейс IComparable, реализация которого позволяет сравнивать объекты не только на равенство, но и на "больше","меньше".Класс реализует методы интерфейса, делая их открытыми для клиентов класса и наследников. Другая стратегия реализации состоит в том, чтобы все или некоторые методы интерфейса сделать закрытыми.Для реализации этой стратегии класс, наследующий интерфейс, объявляет методы без модификатора доступа, что по умолчанию соответствует модификатору private, и уточняет имя метода именем интерфейса. Метод нтерфейса со своим именем закрывается, а потом открывается под тем именем, которое класс выбрал для него. Создать объект класса интерфейса обычным путем с использованием конструктора и операции new нельзя. Тем не менее, можно объявить объект интерфейсного класса и связать его с настоящим объектом путем приведения (кастинга) объекта наследника к классу интерфейса. Это преобразование задается явно. Имея объект, можно вызывать методы интерфейса - даже если они закрыты в классе,для интерфейсных объектов они являются открытыми. При множественном наследовании классов возникает ряд проблем. Они остаются и при множественном наследовании интерфейсов, хотя становятся проще. Рассмотрим две основные проблемы – коллизию имен и наследование от общего предка.наследники не должны требовать изменений своих родителей - они сами должны меняться.Переименование методов интерфейсов иногда невозможно чисто технически, если интерфейсы являются встроенными или поставляются сторонними фирмами. К счастью, мы знаем, как производить переименование метода интерфейса в самом классе наследника. для этого достаточно реализовать методы разных интерфейсов как закрытые, а затем открыть их с переименованием.Отношение порядка на объектах класса Person задается как отношение порядка на фамилиях персон.Так как строки наследуют интерфейс IComparable, то для фамилий персон вызывается метод CompareTo, его результат и возвращается в качестве результата метода CompareTo для персон. Если аргумент метода не будет соответствовать нужному типу, то выбрасывается исключение со специальным уведомлением.Введем теперь в нашем классе Person перегрузку операций отношения.

Вопрос№31.Делегаты.Делегат – это класс.Объявление класса делегата начинается ключ. словом delegate и выглядит следующим образом: ОбъявлениеКлассаДелегата ::=[СпецификаторДоступа] delegate СпецификаторВозвращаемогоЗначения ИмяКлассаДелегата (СписокПараметров); При этом СпецификаторВозвращаемогоЗначения ::= ИмяТипа ИмяКлассаДелегата ::= Идентификатор а синтаксис эл-та СписокПараметров аналогичен списку параметров функции. Но сначала – примеры объявления классов делегатов: delegate int ClassDelegate(int key); delegate void XXX(int intKey, float fKey); Подобие объявления класса-делегата и заголовка функции не случайно. Класс-делегат способен порождать объекты. При этом назначение объекта — представителя класса-делегата заключается в представлении методов (функций-членов) РАЗЛИЧНЫХ классов. Любой класс-делегат наследует System.MulticastDelegate. Это обстоятельство определяет многоадресность делегатов: в ходе выполнения приложения объект-делегат способен запоминать ссылки на произвольное количество функций независимо от их статичности или нестатичности и принадлежности классам. Св-ва и методы классов-делегатов.1.Method — Возвращ. имя метода, на кот. указывает делегат.2.Target- Возвращает имя класса, если делегат указывает на нестатический метод класса. Возвращает знач-е типа null, если делегат указ-ет на статич. Метод. 3.Combine(), operator+(), operator+=(), operator–(), operator–=()- Фун-я и операторные функции. Обеспеч. реализацию многоадресного делегата. 4.GetInvocationList() -Основываясь на внутреннем списке ссылок на функции, строится соответствующий массив описателей типов функций. 5. object DynamicInvoke (object[]args) -В соответствии со списком ссылок обеспечивается выполнение функций, на которые был настроен делегат 6.static Remove()-Статич. метод, обеспеч. удаление эл-ов внутреннего списка ссылок на функции.

Вопрос№32.Коллекции в языке C#. Группы объектов.

В C# под коллекцией понимается некоторая группа объектов. Она упрощает реализацию многих задач в прог-и, предлагая уже готовые решения для построения структур данных.Коллекции разработаны на основе четко определенных интерфейсов, поэтому стандартизируют способы обработки групп объектов.В среде .Net Framework 3 основ. Коллекций: 1.общего назначения 2.специализированные 3.ориентированные на побитовую организацию данных. Коллекции общего назнач-я определены в пространстве имен System.Collection и реализуют структуры данных: стеки, очереди, динамические массивы хэш-таблиц, отсортированный список для хранения пар ключ/значения. Коллекции общего назначения работают с типами данных типа object.Коллекции специального назнач-я определены в пространстве имен System.Collection.Specialized и ориентированны на обработку данных конкретного типа или на обработку данных уникальным способом. В пространстве имен System.Collection определена единственная коллекция, ориентированная на побитовую организацию данных, которая служит для хранения групп битов и поддерживает такой набор операций, который не характерен для коллекций других типов. Коллекции общего назначения.Stack - Частный случай однонаправленного списка: последний пришел — первым вышел;Queue - Частный случай однонаправленного списка: первым пришел — первым вышел; ArrayList -динамич. массив, кот. при необходимости может увеличить свой размер; Hashtable --- Хэш-таблица для пар ключ/значение; SortedList - Отсортированный список пар ключ/значение. Абстрактный тип данных — список — это послед-ть данных a1, a1, …, an (n>=0) одного типа, кол-во элементов n называется длиной списка. Если n>0, то a1 — первый элемент списка, а an — последний. В случае, если n=0, то имеем пустой список, кот. не содержит элементов. Элементы линейно упорядочены в соответствии с их позицией в списке.Список называется однонаправленным, если каждый элемент списка содержит ссылку на следующий элемент. Если каждый элемент содержит 2 ссылки: одну на следующий элемент, другую на предыдущий, то такой список называется двунаправленным или двусвязным. А если последний элемент связать указателем с первым, то получится кольцевой список. Класс Stack — добавление элементов в который и выборка элементов из которого выполняется с одного конца, который называется вершиной стека. При выборке элемент исключается из списка. Др. операции над стеком не определены. Интерфейсы: 1.I.Collection 2.I.Unumerable 3.I.Cloneablе Конструкторы: 1.public Stack (); // созд-ся пустой стек, началь. вместимость кот. равна 10 2.public Stack (int capacity); // созд-ся пустой стек, начальная вместимость кот. равна capacity 3.public Stack (I.Collretion C); // создается пустой стек, кот. содержит элементы коллекции, заданные параметром С и аналогичной им вместимостью. Собственные методы: 1.Contains - Опред-ет, принадлежит ли элемент классу Stack 2.Clear -Удаляет все объекты из класса Stack 3.Peek - Возвращает самый верхний объект класса Stack, но не удаляет его. 4.Pop - Удаляет и возвращает верхний объект класса Stack.5.Push - Вставляет объект в начало класса Stack 6.ToArray - Копирует элементы класса Stack в новый массив. Абстрактный тип данных Queue – частный случай однонаправленного списка, добавление элементов в который выполняется в один конец (хвост), а выборка с другого (голова). Другие операции для очереди не определены, при выборке элемент исключается из очереди. Как и стек, очередь реализует те же интерфейсы. Очередь — динамич. коллекция,размер кот. изменяется. При необходимости увеличения вместимости очереди происходит с коэффициентом роста по умолчанию, равному двум. Конструкторы: 1.public Queue(); // созд-ся пустая очередь, началь. вместимость кот. Равна 32, 2.public Queue(int capacity); // созд-ся пустая очередь, начальная вместимость кот. равна capacity, 3.public Queue(int capacity, float n); // созд-ся очередь, кот. содержит элементы коллекции, коэффициент роста устанавливает параметр n, 4.public Queue(I.Collretion C); // созд-ся пустая очередь, кот. содержит элементы коллекции, заданные параметром С и аналогичной им вместимостью. Методы: 1.Contains -Опр-ет, принадлежит ли элемент классу Stack 2.Clear -Удаляет все объекты из класса Stack 3.Dequeue - Удаляет и возвращает объект в начале класса Queue 4.Enqueue- Добавляет объект в конец класса Queuе 5.Peek - Возвращает объект в начале класса Queue, но не удаляет его 6.ToArray- Копир. элементы класса Queue в новый массив 7.TrimToSize --- Задает значение емкости, равное действительному количеству элементов в классе Queue.Класс ArrayList В С# стандартные массивы имеют фиксированную длину, которая во время выполнения программы может изменяться. Класс ArrayList предназначен для поддержки динамических массивов, которые при необходимости могут увеличиваться или сокращаться. Любой объект класса ArrayList создается с некоторым начальным размером. При превышении этого размера, коллекция автоматически удваивается. В случае удаления объектов, массив можно сократить. Интерфейсы:1.I.Collection 2.I.Unumerable 3.I.Cloneable 4.I.List По мимо методов, реализуемых в этих интерфейсах, класс ArrayList реализует и свои собственные методы: AddRange - Добавляет элементы интерфейса ICollection в конец класса ArrayList BinarySearch - Перегружен. Использует алгоритм двоичного поиска для нахождения определенного элемента в отсортированном классе ArrayList или в его части. Св-во Capacity позволяет установить или узнать емкость вызывающего динамического массива типа ArrayList.

Вопрос№33.Сборки в языке C#. Структура сборки. Класс Assembly определяет Сборку – основной строительный блок Common Language Runtime приложения. Как строительный блок CLR, сборка обладает следующими основными свойствами: возможностью многократного применения; versionable (версифицированностью); самоописываемостью. Сборки бывают: 1.частными (private). Представляют наборы типов, которые могут быть использованы только теми приложениями, где они включены в состав. Располагаются в файлах с расширениями .dll (.exe) и .pdb (program debug Database). 2.общего доступа (shared). Также набор типов и ресурсов внутри модулей (модуль – двоичный файл сборки). Предназначены для использования НЕОГРАНИЧЕННЫМ количеством приложений на клиентском компьютере. Эти сборки устанавливаются не в каталог приложения, а в специальный каталог, называемый Глобальным Кэшем Сборок (Global Assembly Cache – GAC). Загружаемая сборка строится как БИБЛИТОТЕКА КЛАССОВ (файл с расширением .dll), либо как выполняемый модуль (файл с расширением .exe). Если это файл с расширением .dll, то в среде Visual Studio ее использование поддерживается специальными средствами среды. Это "полуавтоматическая" загрузка частной сборки в Reference приложения (Add Reference...). Сборки, располагаемые в .exe-файлах, особой поддержкой для включения сборки в состав приложения не пользуются. Ниже представлены некоторые члены класса сборки.Откр св-ва.1.CodeBase-Возвращает местонахождение сборки, указанное первоначально, например в объекте AssemblyName 2.EntryPoint-Возвращает точку входа для этой сборки 3.Evidence -Возвращает свидетельство для этой сборки 4.FullName - Возвращает отображаемое имя сборки. Открытые события ModuleResolve -Возникает, когда загрузчик классов общеязыковой среды выполнения не может обработать ссылку на внутренний модуль сборки, используя обычные средства. Защищенные методы 1.Finalize (унаследовано от Object) --- Переопределен. Позволяет объекту Object попытаться освободить ресурсы и выполнить другие завершающие операции, перед тем как объект Object будет уничтожен в процессе сборки мусора. В языках C# и C++ для функций финализации используется синтаксис деструктора 2.MemberwiseClone (унаследовано от Object) --- Создает неполную копию текущего Object.В ходе выполнения приложения класс Assembly позволяет:1.получать информацию о самой сборке; 2.обращаться к членам класса, входящим в сборку; 3.загружать другие сборки.

Вопрос№34.Обработка ошибок. Работа с исключениями.Одним из основных назначений .NET CLR является недопущение ошибок. Это достигается такими средствами, как автоматическое управление памятью и ресурсами в управляемом коде или хотя бы их обнаружение во время компеляции благодаря строгой типизированной системе. Однако, некоторые ошибки можно обнаружить только в период выполнения, а это значит, что для всех языков, соответствующих спецификации Common Language Specification должен быть предусмотрен единый метод реакции на ошибки. Обзор обработки исключений. Исключения — это условия, при которых нормальный вход в программу, т.е. последовательность вызовов методов в стеке вызовов, невохможен или нежелателен. Надо понимать разницу между исключениями и ожидаемыми событиями (скажем, обнаружение конца файла). Если имеется метод, который последовательно считывает файл, то такое событие не является исключительным, и оно не должно вызывать прерывания выполнения программы. Если идет попытка чтения файла, а ОС уведомляет о дисковой ошибке, то это искдючительная ошибка, именно такая, что может повлиять на нормальный ход работы метода при попытке продолжить считывание файла. Большинство исключений связаны и с другой проблемой — контекстом. Один метод обнаруживает наличие исключительной ситуации, но оказывается не в том контексте, чтобы реагировать на эту ошибку. Он сигнализирует исполняющей среде о наличии ошибки. Исполнительная среда последовательно проходит по стеку вызовов, пока не находит метод, способный правильно работать с ошибкой.Основной синтаксис обработки исключений При обработке исключений используются всего 4 ключевых слова: try, catch, throw, finally.Когда метод не может выполнить свою задачу, т.е. когда он определяет исключительную ситуацию, то он передает исключения вызывающему методу через ключевое слово throw. Вызывающий метод (если предположить, что он способен, т.е. обладает достаточным контекстом для работы с исключениями) полусает это исключение посредством ключевого слова catch и решает, что предпринять.Передача исключения.Чтобы методу уведомить вызовавший метод, что возникла ошибка, он использует ключевое слово throw [выражение] При передаче исключения необходимо передать объект типа System.Exception или произвольный класс. Улавливание (нахождение) исключения.Если метод может передавать исключению, то должна быть и обратная сторона, которая находит это исключение.Ключевое слово catch определяет блок кода, который выполняется при возникновении исключения данного типа. Содержащийся в блоке код называется обработчиком исключений. Не каждый метод должен иметь дело с каждым переданным исключением. Прежде всего потому, что метод модет не иметь контекста для адекватной обработки ошибки. Ошибка должна обрабатываться кодом, имеющим достаточный контекст, чтобы корректно осуществлять реакцию на ошибку. Для этого используются ключевые слова try и catch. Для обнаружения исключения нужно ограничить код блоком try, а затем указать какие типы исключений будут обрабатываться в блоке catch. Все операторы из блока try будут обрабатывать по порядку, только если один из методов не передаст исключение. Если это произойдет, то управление будет передано на соответствующую строку блока catch. При передаче исключения управление передается по стеку вызовов наверх, пока не будет найден блок catch для исключения данного типа. Если подходящий блок catch не обнаружен, то приложение прерывается. Следовательно, если один метод вызывает другой, передающий исключения, то структура приложения должна быть такой, что метод в стеке вызовов смог обрабатывать исключения. Повторная передача исключения. Случается, что метод, уловивший исключения и сделававший все,что он может в своем контексте, затем повторно передает исключение выше. Освобождение ресурсов с помощью finally. Один трудный вопрос с обработкой ошибок связан с тем, что код всегда зависит от того, уловлено ли исключение. Например, вы выделили ресурс такой, как физическое устройство или файл данных. Теперь предположим, что вы открыли этот ресурс и вызвали метод, передающий исключение. Независимо от того, может ли ваш метод прожолжить работу с ресурсом, вам в любом случае нужно освободить или закрыть ресурс. Здесь применяется ключевое слово finally. Оно позволяет избежать двойного кодирования, освобождения ресурсов в блоке catch и после блоков try/catch. Независимо от того, передано ли исключение, будет выполнен код в блоке finalу.Улавливание множества типов исключений. В различных ситуациях может потребоваться блок try{} для обнаружения исключения различных типов. Так, о методе может быть известно, что он передает исключение нескольких различных типов или в одном блоке try потребуется вызов нескольких методов, причем в каждом методе известно, что он передает исключение своего типа, тогда добавляется для каждого типа свой блок catch. Блок try не должен улавливать все возможные исключения, которые может послать содержащий в нем метод. CLR автоматически продолжает передавать управление вверх по стеку до тех пор пока не обнаружиться метод улавливающий исключение, промежуточные методы могут игнорировать исключения, которые они не могут обрабатывать. Проблема создания блоков catch. Единственное, что должно быть в блоке catch, - это код, который хотя бы частично улавливает исключение. Например, можно произвести некоторые действия, возможные на момент исключения и повторно передать его, чтобы возможной была его дальнейшая обработка.

Вопрос№35.Безопасность в .NET. Безопасность доступа кода. Поддержка безопасности в .NET Framework.

Безопасность является краеугольным камнем .NET. На всех этапах создания и выполнения программ происходят самые различные проверки - от проверки прав на доступ к коду до разрешений на ресурсы. Вот некоторые из типов проверок безопасности: 1.Безопасность типов. Программы, гарантирующие безопасность данных, обращаются только к тем участкам памяти, которые были выделены для них. Доступ к объектам осуществляется только через специальные интерфейсы, в которые встроены проверка безопасности. 2.Подлинность кода. Загрузчик классов сохраняет информацию об исходных текстах всех классов, которые были загружены. 3.Разрешения на доступ к ресурсам. Ресурсы обычно ассоциированы с системой. В качестве ресурсов могут выступать файлы, сетевые соединения, право вызова неуправляемых API (unmanaged APIs). 4.Декларативная безопасность. Данный механизм предоставляет возможность встраивать проверки безопасности прямо в код путем аннотации классов, полей или методов. 5.Императивная безопасность. Обычный код внутри разрабатываемого метода, который проверяет права на данную операцию во время запуска. Такие проверки важны для доступа к файлам, пользовательскому интерфейсу и т.п. Другие модели обеспечения безопасности: 1.Модель политик доступа 2.Модель ролей Модель политик доступа. Политики позволяют автоматически присваивать коду определенные привилегии, основываясь на том, откуда были получены исходные тексты данного приложения. Пользователи могут изменять эти политики. Модель ролей. Эта модель безопасности проверяет, в какой роли выступает пользователь и разрешает/отказывает в доступе в зависимости от этого. Модель безопасности .NET Framework. Модель безопасности .NET Framework основывается на безопасности доступа кода (Code Access Security, CAS) и ролевой безопасности. Под безопасностью доступа кода подразумевается разрешение на использование защищенных данных вашим приложением только в том случае, когда у него есть соответствующие права доступа. В тот момент, когда ваше приложение отправляет запрос на использование того или иного ресурса, .NET Framework проверяет наличие соответствующих прав доступа, и если таковых не обнаружено, запрещает доступ. Под ролевой безопасностью подразумевается использование встроенных ролей. В зависимости от роли работающего пользователя приложение использует те или иные ресурсы. Уровни безопасности Существует несколько уровней безопасности: сеть, компьютер, пользователь, домен приложения (дополнительный уровень). Использование безопасности доступа кода Настройки безопасности каждого компьютера индивидуальны. Они меняются в зависимости от пользователя, администратора компьютера или администратора сети, и нет никакой гарантии, что ваше приложение получит необходимые разрешения на выполнение операций. Взаимодействие с системой безопасности во время выполнения осуществляется двумя способами: императивным и декларативным. Декларативный способ взаимодействия осуществляется с помощью атрибутов, императивный – с помощью объектов классов в вашем приложении. Некоторые операции могут быть выполнены с помощью одного из способов, а некоторые — любым из них. Основной задачей на стадии разработки остается лишь документирование необходимых приложению разрешений для того, чтобы быть уверенным, что приложение их получит. Это делается с помощью запроса разрешений и утилит настройки политики безопасности. Для того чтобы добавить запрос на определенное разрешение, необходимо добавить соответствующий атрибут в файл ApplicationInfo.cs проекта. При компиляции сборки эти атрибуты сохранятся в метаданных. Запросы на разрешения проверяются CLR во время загрузки сборки. Существует три вида запросов: 1.Запрос минимального набора разрешений (RequestMinimum) --- Запрашивает необходимый минимум для корректной работы приложения. Если это разрешение не назначено политикой безопасности, то CLR не выполнит операции, а сгенерирует исключение типа PolicyException. Этим запросом необходимо пользоваться только для минимальных разрешений; 2.Запрос дополнительного набора разрешений (RequestOptional) --- Представляет набор разрешений, с которыми может работать ваше приложение, но без которых оно сможет корректно выполнять действия. Этим запросом описывают дополнительную функциональность приложения. Если это разрешение не назначено политикой безопасности, то приложение будет продолжать работать; 3.Запрос на отказ от разрешений (RequestRefused) --- Указываются разрешения, которые ваше приложение использовать не будет. Запросы указываются для обеспечения дополнительной безопасности.

Вопрос№36.Управление политиками безопасности.

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

Политика ИБ является объектом стандартизации. Некоторые страны имеют национальные стандарты, определяющие основное содержание подобных документов. Имеются ряд ведомственных стандартов и международные стандарты в этой области (ISO 17799).

В России к нормативным документам, определяющим содержание политики ИБ, относится ряд РД Гостехкомиссии. В отечественных и международные стандартах используются сходная методология, однако ряд вопросов в отечественных РД не рассмотрен или рассмотрен менее подробно. Таким образом, при разработке политики ИБ целесообразно использовать передовые зарубежные стандарты, позволяющие разработать более качественные документы, полностью соответствующие отечественным РД.

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

Основные этапы:

Разработка концепции политики информационной безопасности

Описание границ системы и построение модели ИС с позиции безопасности

Анализ рисков: формализация системы приоритетов организации в области информационной безопасности, выявление существующих рисков и оценка их параметров

Анализ возможных вариантов контрмер и оценка их эффективности.

Выбор комплексной системы защиты на всех этапах жизненного цикла.

Формирование политики и процедур безопасности означает выработку плана действий по поддержанию режима информационной безопасности. Этот план содержится в следующих документах:

Концепция политики ИБ

Модель автоматизированной системы с позиции ИБ

Анализ рисков

Управление рисками

Комплексная система обеспечения ИБ

Информационная безопасность

Безопасность информации

Information security

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

Информационная безопасность имеет три основные составляющие:

-1- конфиденциальность - защита чувствительной информации от несанкционированного доступа;

-2- целостность - защита точности и полноты информации и программного обеспечения;

-3- доступность - обеспечение доступности информации и основных услуг для пользователя в нужное для него время.

Вопрос№37. Использование динамического массива.

using System;

using System.Collections;

namespace MyProgram

{

class Program

{

static void ArrayPrint(string s, ArrayList a)

{

Console.WriteLine(s);

foreach (int i in a)

Console.Write(i + " ");

Console.WriteLine();

}

static void Main(string[] args)

{

ArrayList myArray = new ArrayList();

Console.WriteLine("Начальная емкость массива: " + myArray.Capacity);

Console.WriteLine("Начальное количество элементов: " + myArray.Count);

Console.WriteLine("\nДобавили 5 цифр");

for (int i = 0; i < 5; i++) myArray.Add(i);

Console.WriteLine("Текущая емкость массива: " + myArray.Capacity);

Console.WriteLine("Текущее количество элементов: " + myArray.Count);

ArrayPrint("Содержимое массива", myArray);

Console.WriteLine("\nОптимизируем емкость массива");

myArray.Capacity=myArray.Count;

Console.WriteLine("Текущая емкость массива: " + myArray.Capacity);

Console.WriteLine("Текущее количество элементов: " + myArray.Count);

ArrayPrint("Содержимое массива", myArray);

Console.WriteLine("\nДобавляем элементы в массив");

myArray.Add(10);

myArray.Insert(1, 0);

myArray.AddRange(myArray);

Console.WriteLine("Текущая емкость массива: " + myArray.Capacity);

Console.WriteLine("Текущее количество элементов: " + myArray.Count);

ArrayPrint("Содержимое массива", myArray);

Console.WriteLine("\nУдаляем элементы из массива");

myArray.Remove(0);

myArray.RemoveAt(10);

Console.WriteLine("Текущая емкость массива: " + myArray.Capacity);

Console.WriteLine("Текущее количество элементов: " + myArray.Count);

ArrayPrint("Содержимое массива", myArray);

Console.WriteLine("\nУдаляем весь массив");

myArray.Clear();

Console.WriteLine("Текущая емкость массива: " + myArray.Capacity);

Console.WriteLine("Текущее количество элементов: " + myArray.Count);

ArrayPrint("Содержимое массива", myArray);

}

}

}

Вопрос№38.Хэш таблица.

Класс Hashtable предназначен для создания коллекции, в которой для хранения объектов используется хеш-таблица. В хеш-таблице для хранения информации используется механизм, именуемый хешированием (hashing). Суть хеширования состоит в том, что для определения уникального значения, которое называется хеш-кодом, используется информационное содержимое соответствующего ему ключа. Хеш-код затем используется в качестве индекса, по которому в таблице отыскиваются данные, соответствующие этому ключу. Преобразование ключа в хеш-код выполняется автоматически, т.е. сам хеш-код вы даже не увидите. Но преимущество хеширования - в том, что оно позволяет сокращать время выполнения таких операций, как поиск, считывание и запись данных, даже для больших объемов информации. Класс Hashtable реализует стандартные интерфейсы IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback и ICloneable. Размер хеш-таблицы может динамически изменяться. Размер таблицы увеличивается тогда, когда количество элементов превышает значение, равное произведению вместимости таблицы и ее коэффициента заполнения, который может принимать значение на интервале от 0,1 до 1,0. По умолчанию установлен коэффициент равный 1,0. Разработаем простейшую записную книжку, в которую можно добавлять и удалять телефоны, а также осуществлять поиск номера телефона по фамилии и фамилии по номеру телефона.

using System;

using System.Collections;

using System.IO;

using System.Text;

namespace MyProgram

{

class Program

{

static void printTab(string s, Hashtable a)

{

Console.WriteLine(s);

ICollection key = a.Keys; //Прочитали все ключи

foreach (string i in key)//использование ключа для получения значения

{

Console.WriteLine(i + "\t" + a[i]);

}

}

static void Main(string[] args)

{

StreamReader fileIn = new StreamReader("t.txt",Encoding.GetEncoding(1251));

string line;

Hashtable people = new Hashtable();

while ((line = fileIn.ReadLine()) != null) //цикл для организации обработки файла

{

string [] temp = line.Split(' ');

people.Add(temp[0],temp[1]);

}

fileIn.Close();

printTab("Исходные данные: ", people);

Console.WriteLine("Введите номер телефона");

line = Console.ReadLine();

if (people.ContainsKey(line)) Console.WriteLine(line + "\t" + people[line]);

else

{

Console.WriteLine("Такого номера нет в записной книжке.\nВведите фамилию: ");

string line2=Console.ReadLine();

people.Add(line,line2);

}

printTab("Исходные данные: ", people);

Console.WriteLine("Введите фамилию для удаления");

line = Console.ReadLine();

if (people.ContainsValue(line))

{

ICollection key =people.Keys; //Прочитали все ключи

Console.WriteLine(line);

string del="";

foreach (string i in key)//использование ключа для получения значения

if (string.Compare((string)people[i], line) == 0)

{

del = i;

break;

}

Console.WriteLine(del + "\t" + people[del] + "- данные удалены!!!");

people.Remove(del);

printTab("Измененные данные: ", people);

}

else Console.WriteLine("Такого абонента в записной книжке нет ");

}

}

}

_________t.txt____________

12-34-56 Иванов

78-90-12 Петров

34-56-78 Семёнов

90-11-12 Пиманов

Вопрос№39 выражения в языке C#.

Выражения строятся из операндов (констант, переменных, функций) объединенных знаками операций и скобками.

При вычислении выражения определяется:

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

  2. Правила задают приоритет операций. Для операции 1 приоритета порядок выполнения: слева направо или справа налево.

  3. Преобразование типов операндов и выбор реализации для перегруженных операций.

  4. Типы, значения результатов выполнения операции над заданными значениями операндов определенного типа.

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

Приоритет и порядок выполнения операций:

Приоритет

Категории

Операции

Порядок

0

Первичные

(expr) x.y f(x) a[x] x++ x—new sizeof(t) typeof(t) checked(expr) unchecked(expr)

С - П

1

Унарные

+ - ! ~ ++x --x (T)x

С - П

2

Мультипликативные (умножение)

* / %

С - П

3

Аддитивные (Сложение)

+ -

С - П

4

Сдвиг

<< >>

С - П

5

Отношения, проверка типов

< > <= >= is as

С - П

6

Эквивалентность

== !=

С - П

7

Логическое И

&

С - П

8

Логическое исключающее ИЛИ (XOR)

^

С - П

9

Логическое ИЛИ (OR)

|

С - П

10

Условное И

&&

С - П

11

Условное ИЛИ

||

С - П

12

Условное выражение

? :

С - Л

13

Присваивание

= *= /= %= += -= <<= >>= &= ^= |=

С - Л


Вопрос№40 Инструкция Using .

Часто возникает необходимость освободить ресурсы некоторого объекта независимо от того записано там исключение или нет. Это можно сделать вручную, поместив блок кода внутри try и добавить блок finally, в котором освобождаются ресурсы объекта с помощью метода IDispose.

Удобнее использовать конструкцию Using. При ее использовании код будет помещен в блок try, а после try будет добавлен в блок finally.

Пример:

Using (Some Class sc = new Some Class())

{

Sc.DoSomething():

}

Some Class sc = new some Class():

Try

{

Sc.DoSomething():

}

Finally

{

If (sc !=null) (( IDisposible) sc.Dispose))

}

Вопрос№41 Средства ввода-вывода

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

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

Вопрос№43Атрибуты

Атрибуты предоставляют универсальные средства связи данных (в виде аннотаций) с типами, определенными на С#. Вы можете применять их для определения информации периода разработки (например, документации), периода выполнения (например, имя столбца БД) или даже характеристик поведения периода выполнения (например, может ли данный член участвовать в транзакции). Возможности атрибутов бесконечны. Поскольку вы можете создавать атрибуты на основе любой информации, существует стандартный механизм определения самих атрибутов и запроса членов или типов в период выполнения как связанных с ними атрибутов.Лучше объяснить использование атрибутов на примере. Допустим, у вас есть приложение, хранящее некоторые данные в реестре. Одна из проблем разработки связана с выбором места хранения информации о разделе реестра. В большинстве сред разработки она, как правило, хранится в файле ресурсов, в константах или даже жестко запрограммирована в вызовах API реестра. Однако мы снова имеем ситуацию, когда неотъемлемая часть класса хранится отдельно от определения остальной части класса. Атрибуты позволяют "прикреплять" эту информацию к членам класса, получая полностью самоописывающийся компонент. Вот пример, иллюстрирующий, как это может выглядеть, если предположить, что атрибут RegistryKey уже определен:

class MyClass {

[RegistryKey(HKEY_CURRENT_USER, "foo")] public int Foo; }Чтобы прикрепить определенный атрибут к типу или члену С#, нужно просто задать данные атрибута в скобках перед целевым типом или членом. В нашем примере мы прикрепили атрибут RegistryKey к полю MyClass.Foo. Как вы вскоре увидите, все, что нам надо сделать в период выполнения, — это запросить значение поля, связанное с разделом реестра и использовать его, чтобы сохранить дату в реестре.Определение атрибутов В предыдущем примере синтаксис прикрепления атрибута к типу или члену похож на тот, что применяется при создании экземпляра класса. Дело в том, что атрибут на самом деле является классом, производным от базового класса System.Attribute.