Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методичка по С#

.pdf
Скачиваний:
276
Добавлен:
13.02.2015
Размер:
3.13 Mб
Скачать

 

 

 

 

 

 

 

 

 

 

101

 

 

 

 

FlattenHierarchy

Определяет,

что должны быть возвращены статические члены

 

 

вверх по иерархии. Статические члены — это поля, методы,

 

 

события и свойства. Вложенные типы не возвращаются.

 

 

GetField

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

 

 

 

 

GetProperty

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

 

 

свойства.

 

 

 

 

 

 

 

 

 

 

IgnoreCase

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

 

 

имени члена.

 

 

 

 

 

 

 

 

 

IgnoreReturn

Используется при COM-взаимодействии для определения того, что

 

 

возвращаемое значение члена может быть проигнорировано.

 

 

Instance

Определяет,

что в

поиск

должны

быть включены

члены

 

 

экземпляра.

 

 

 

 

 

 

 

 

 

 

InvokeMethod

Определяет, что метод должен быть вызван. Метод не может быть

 

 

ни конструктором, ни инициализатором типа.

 

 

NonPublic

Определяет,

что в поиск должны быть включены члены

 

 

экземпляра, не являющиеся открытыми (public).

 

 

OptionalParamBinding

Возвращает набор членов, у которых количество параметров

 

 

соответствует

количеству

переданных

аргументов.

Флаг

 

 

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

 

 

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

 

 

аргументов

(varargs). Этот флаг должен использоваться только

 

 

с Type.InvokeMember.

 

 

 

 

 

 

 

 

 

Параметры со значениями

по

умолчанию

используются только в

 

 

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

 

 

последними аргументами.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Public

Определяет,

что

открытые

(public)

члены

должны быть включены

 

 

в поиск.

 

 

 

 

 

 

 

 

 

 

PutDispProperty

Определяет, что для COM-объекта должен быть вызван член

 

 

PROPPUT. PROPPUT задает устанавливающую свойство функцию,

 

 

использующую значение. Следует использовать PutDispProperty,

 

 

если для свойства заданы и PROPPUT, и PROPPUTREF и нужно

 

 

различать вызываемые методы.

 

 

 

 

 

 

PutRefDispProperty

Определяет, что для COM-объекта должен быть вызван член

 

 

PROPPUTREF. PROPPUTREF использует устанавливающую свойство

 

 

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

 

 

использовать PutRefDispProperty, если для свойства заданы и

 

 

PROPPUT, и PROPPUTREF и нужно различать вызываемые методы.

 

 

 

 

SetField

Определяет, что должно устанавливаться значение указанного

 

 

поля.

 

 

 

 

 

 

 

 

 

 

SetProperty

Определяет, что должно устанавливаться значение указанного

 

 

свойства. Для COM-свойств задание этого флага связывания

 

 

эквивалентно заданию PutDispProperty и PutRefDispProperty.

 

Static

Определяет,

что

в

поиск

должны

быть

 

включены статические

 

 

члены.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

SuppressChangeType

Не реализован.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Далее демонстрируется применение класса Type, в частности, варианты использования метода-члена класса Type InvokeMember, который обеспечивает выполнения методов и свойств класса.

using System;

using System.Reflection;

// В классе объявлены поле myField, конструктор, метод String ToString(), свойство. class MyType

{

int myField;

public MyType(ref int x)

{

x *= 5;

}

public override String ToString()

{

Console.WriteLine(“This is: public override String ToString() method!”); return myField.ToString();

}

101

102

//Свойство MyProp нашего класса обладает одной замечательной особенностью:

//значение поля myField объекта-представителя класса MyType не может быть

//меньше нуля. Если это ограничение нарушается - возбуждается исключение. public int MyProp

{

get

{

return myField;

}

set

{

if (value < 1)

throw new ArgumentOutOfRangeException(“value”, value, “value must be > 0”); myField = value;

}

}

}

class MyApp

{

static void Main()

{

// Создали объект-представитель класса MyType

//на основе объявления класса MyType. Type t = typeof(MyType);

//А это одномерный массив объектов, содержащий ОДИН элемент.

//В этом массиве будут передаваться параметры конструктору.

Object[] args = new Object[] {8};

Console.WriteLine(“The value of x before the constructor is called is {0}.”, args[0]);

//Вот таким образом в рамках технологии отражения производится

//обращение к конструктору. Наш объект адресуется по ссылке obj.

Object obj = t.InvokeMember( null,

//____________________________

BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |

BindingFlags.CreateInstance, // Вот распоряжение о создании объекта…

//____________________________

null,

null,

args // А так организуется передача параметров в конструктор.

);

Console.WriteLine(“Type: ” + obj.GetType().ToString());

Console.WriteLine(“The value of x after the constructor returns is {0}.”, args[0]);

//Изменение (запись и чтение) значения поля myField. Только что созданного

//объекта-представителя класса MyType. Как известно, этот объект адресуется по

//ссылке obj. Мы сами его по этой ссылке расположили!

t.InvokeMember(

“myField”, // Будем менять значение поля myField… //______________________________

BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |

BindingFlags.SetField, // Вот инструкция по изменению значения поля.

//_______________________________

null,

obj, // Вот указание на то, ГДЕ располагается объект…

new Object[] {5} // А вот и само значение. Оно упаковывается в массив объектов.

);

int v = (Int32) t.InvokeMember(

“myField”,

//______________________________

BindingFlags.DeclaredOnly |

102

103

BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |

BindingFlags.GetField, // А сейчас мы извлекаем значение поля myField. //______________________________

null,

obj, // “Работаем” всё с тем же объектом. Значение поля myField // присваивается переменной v.

null

);

//Вот распечатали это значение.

Console.WriteLine(“myField: ” + v);

//“От имени” объекта будем вызывать нестатический метод. String s = (String) t.InvokeMember(

“ToString”, // Имя переопределённого виртуального метода.

//______________________________

BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |

BindingFlags.InvokeMethod, // Сомнений нет! Вызываем метод! //______________________________

null,

obj, // От имени нашего объекта вызываем метод без параметров. null

);

//Теперь обращаемся к свойству.

Console.WriteLine(“ToString: “ + s);

//Изменение значения свойства. Пытаемся присвоить недозволенное значение.

//И посмотрим, что будет… В конце-концов, мы предусмотрели перехватчик исключения.

try

{

t.InvokeMember(

“MyProp”, // Работаем со свойством.

//______________________________

BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |

BindingFlags.SetProperty, // Установить значение свойства. //______________________________

null,

obj,

new Object[] {0} // Вот пробуем через обращение к свойству

//установить недозволенное значение.

);

}

catch (TargetInvocationException e)

{

//Фильтруем исключения... Реагируем только на исключения типа

//ArgumentOutOfRangeException. Все остальные «проваливаем дальше».

if (e.InnerException.GetType() != typeof(ArgumentOutOfRangeException)) throw;

//А вот как реагируем на ArgumentOutOfRangeException.

//Вот так скромненько уведомляем о попытке присвоения запрещённого значения. Console.WriteLine(“Exception! Catch the property set.”);

}

t.InvokeMember(

“MyProp”,

//______________________________

BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |

BindingFlags.SetProperty, // Установить значение свойства.

//______________________________

null,

obj,

new Object[] {2} // Вновь присваиваемое значение. Теперь ПРАВИЛЬНОЕ.

103

104

);

v = (int) t.InvokeMember( “MyProp”, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance |

BindingFlags.GetProperty, // Прочитать значение свойства. null,

obj, null

);

Console.WriteLine(“MyProp: “ + v);

}

}

Ну вот. Создавали объект, изменяли значение его поля (данного-члена), вызывали его (нестатический) метод, обращались к свойству (подсовывали ему некорректные значения). И при этом НИ РАЗУ НЕ НАЗЫВАЛИ ВЕЩИ СВОИМИ ИМЕНАМИ! В сущности, ЭТО И ЕСТЬ ОТРАЖЕНИЕ.

Атрибуты

Атрибут – средство добавления ДЕКЛАРАТИВНОЙ информации к элементам программного кода. Назначение атрибутов – внесение всевозможных не предусмотренных обычным ходом выполнения приложения изменений:

описание взаимодействия между модулями,

дополнительная информация, используемая при работе с данными (управление сериализацией),

отладка,

много чего другого.

Эта декларативная информация составляет часть метаданных кода. Она может быть использована при помощи механизмов отражения.

Структура атрибута регламентирована. Атрибут – это класс. Общий предок всех атрибутов – класс System.Attribute.

Информация, закодированная с использованием атрибутов, становится доступной

впроцессе ОТРАЖЕНИЯ (рефлексии типов). Атрибуты типизированы.

.NET способна прочитать информацию в атрибутах и использовать её в соответствии с предопределёнными правилами или замыслами разработчика. Различаются

Предопределённые атрибуты. В .NET реализовано множество атрибутов с предопределёнными значениями:

DllImport – для загрузки .dll файлов.

Serializable – означает возможность сериализации свойств объектапредставителя класса.

NonSerialized – обозначает данные-члены класса как несериализуемые.

Карандаши не сереализуются.

 

Производные (пользовательские)

атрибуты могут определяться и использоваться

в соответствии с замыслами

разработчика. Возможно создание собственных

(пользовательских) атрибутов. Главные условия:

соблюдение синтаксиса,

 

соблюдение принципа наследования.

В основе пользовательских атрибутов – всё та же система типов с наследованием от базового класса System.Attribute.

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

Добавлять атрибуты можно к: сборкам, классам,

элементам класса,

104

105

структурам,

элементам структур,

параметрам,

возвращаемым значениям.

Следующий пример является демонстрацией объявление и применения производных атрибутов.

using System;

using System.Reflection;

namespace CustomAttrCS

{

//Перечисление of animals.

//Start at 1 (0 = uninitialized). public enum Animal

{

//Pets.

Dog = 1, Cat, Bool,

}

//Перечисление of animals.

//Start at 1 (0 = uninitialized). public enum Color

{

//Colors.

Red = 1, Brown, White,

}

// Класс пользовательских атрибутов.

public class AnimalTypeAttribute : Attribute {//====================================================================== // Данное-член типа перечисление.

protected Animal thePet;

protected string WhoIs(Animal keyPet)

{

string retStr = “”; switch (keyPet)

{

case Animal.Dog: retStr = “This is the Dog!”; break; case Animal.Cat: retStr = “This is the Cat!”; break; case Animal.Bool: retStr = “This is the Bool!”; break; default: retStr = “Unknown animal!”; break;

}

return retStr;

}

//Конструктор вызывается при установке атрибута. public AnimalTypeAttribute(Animal pet)

{

thePet = pet; Console.WriteLine(«{0}», WhoIs(pet));

}

//Свойство, демонстрирующее значение атрибута. public Animal Pet

{

get

{

return thePet;

}

set

{

105

106

thePet = Pet;

}

}

}//======================================================================

//Ещё один класс пользовательских атрибутов. public class ColorTypeAttribute : Attribute

{//======================================================================

//Данное-член типа перечисление.

protected Color theColor;

//Конструктор вызывается при установке атрибута. public ColorTypeAttribute(Color keyColor)

{

theColor = keyColor;

}

//Свойство, демонстрирующее значение атрибута. public Color ColorIs

{

get

{

return theColor;

}

set

{

theColor = ColorIs;

}

}

}//======================================================================

//A test class where each method has its own pet.

class AnimalTypeTestClass {//======================================================================

//Содержит объявления трёх методов, каждый из которых

//предваряется соответствующим ПОЛЬЗОВАТЕЛЬСКИМ атрибутом.

//У метода может быть не более одного атрибута данного типа.

[AnimalType(Animal.Dog)]

[ColorType(Color.Brown)] public void DogMethod()

{

Console.WriteLine(“This is DogMethod()...”);

}

[AnimalType(Animal.Cat)] public void CatMethod()

{

Console.WriteLine(“This is CatMethod()...”);

}

[AnimalType(Animal.Bool)]

[ColorType(Color.Red)]

public void BoolMethod(int n, string voice)

{

int i;

Console.WriteLine(“This is BoolMethod!”);

if (n > 0) for (i = 0; i < n; i++)

{

Console.WriteLine(voice);

}

}

}//======================================================================

class DemoClass {//====================================================================== static void Main(string[] args)

{

int invokeFlag;

106

107

int i;

//И вот ради чего вся эта накрутка производилась...

//Объект класса AnimalTypeTestClass под именем testClass

//представляет собой КОЛЛЕКЦИЮ методов, каждый из которых

//снабжён соответствующим ранее определённым пользовательским

//СТАНДАРТНЫМ атрибутом. У класса атрибута AnimalTypeAttribute есть всё,

//что положено иметь классу, включая конструктор.

AnimalTypeTestClass testClass = new AnimalTypeTestClass();

//Так вот создали соответствующий объект-представитель класса...

//Объект-представитель класса сам может служить источником информации

//о собственном классе. Информация о классе представляется методом GetType()

//в виде объекта - представителя класса Type. Информационная капсула!

Type type = testClass.GetType();

//Из этой капсулы можно извлечь множество всякой «полезной» информации...

//Например, можно получить коллекцию (массив) элементов типа MethodInfo

//(описателей методов), содержащую список описателей методов, объявленных

//в данном классе. В список будет включена информация о ВСЕХ методах класса.

//О тех, которые были определены явным образом и те, которые были унаследованы

//от базовых классов. И по этому списку описателей методов мы пройдём

//победным маршем («Ha-Ha-Ha») оператором foreach.

i = 0;

foreach(MethodInfo mInfo in

type.GetMethods())

{

invokeFlag = 0;

Console.WriteLine(“#####{0}#####{1}#####”, i, mInfo.Name);

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

//которыми метод был снабжён при объявлении класса.

foreach (Attribute attr in

Attribute.GetCustomAttributes(mInfo))

{

Console.WriteLine(“~~~~~~~~~~”);

// Check for the AnimalType attribute.

if (attr.GetType() == typeof(AnimalTypeAttribute))

{

Console.WriteLine(“Method {0} has a pet {1} attribute.”, mInfo.Name,

((AnimalTypeAttribute)attr).Pet);

// Посмотрели значение атрибута - и если это Animal.Bool - подняли флажок.

if (((AnimalTypeAttribute)attr).Pet.CompareTo(Animal.Bool) == 0) invokeFlag++;

}

if (attr.GetType() == typeof(ColorTypeAttribute))

{

Console.WriteLine(“Method {0} has a color {1} attribute.”, mInfo.Name,

((ColorTypeAttribute)attr).ColorIs);

// Посмотрели значение атрибута - и если это Animal.Bool - подняли флажок.

if (((ColorTypeAttribute)attr).ColorIs.CompareTo(Color.Red) == 0) invokeFlag++;

}

//И если случилось счастливое совпадение значений атрибутов метода,

//метод выполняется.

//Метод Invoke в варианте с двумя параметрами:

//объект-представитель исследуемого класса

//(в данном случае AnimalTypeTestClass), и массив объектов - параметров. if (invokeFlag == 2)

{

object[] param = {5,”Mmmuuu-uu-uu!!! Mmm...”}; mInfo.Invoke(new AnimalTypeTestClass(),param);

}

Console.WriteLine(“~~~~~~~~~~”);

}

107

108

Console.WriteLine(“#####{0}#####”, i); i++;

}

}

}//======================================================================

}

Сборка. Класс Assembly

Класс Assembly определяет Сборку – основной строительный блок common language runtime приложения. Как строительный блок clr, сборка обладает следующими основными свойствами:

возможностью многократного применения,

versionable (версифицированностью),

самоописываемостью.

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

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

Сборки бывают:

частными (private). Представляют наборы типов, которые могут быть использованы только теми приложениями, в состав которых они входят. Располагаются в файлах с расширениями .dll (.exe) и .pdb (program debug Database). Для того чтобы использовать в приложении частную сборку, её надо ВКЛЮЧИТЬ в приложение, то есть, разместить в каталоге приложения (application directory) или в одном из его подкаталогов.

общего доступа (shared). Также набор типов и ресурсов внутри модулей (модуль

– двоичный файл сборки). Предназначены для использования НЕОГРАНИЧЕННЫМ количеством приложений на клиентском компе. Эти сборки устанавливаются не в каталог приложения, а в специальный каталог, называемый Глобальным Кэшем Сборок (Global Assembly Cache - GAC). Этот каталог на платформе Windows XP

имеет путь C:\WINDOWS\assembly. Таким образом, в .NET ВСЕ совместно используемые сборки собираются в одном месте. Имя (“общее имя” или “строгое имя”) сборки общего доступа строится с использованием информации о версии сборки.

Загружаемая сборка строится как БИБЛИТОТЕКА КЛАССОВ (файл с расширением

.dll), либо как выполняемый модуль (файл с расширением .exe).

Если это файл с расширением .dll, то в среде Visual Studio её использование поддерживается специальными средствами среды. Это “полуавтоматическая” загрузка частной сборки в Reference приложения (Add Reference…). Сборки, располагаемые в .exe файлах, особой поддержкой для включения сборки не состав приложения не пользуется.

Для анализа сборки применяется утилита IlDasm.exe, которую можно подключить

кнепосредственно вызываемому из среды разработки VisualStudio списку утилит. Ниже представлены члены класса Сборки.

Открытые свойства

CodeBase

Возвращает

местонахождение

сборки,

указанное

 

первоначально, например, в объекте AssemblyName.

EntryPoint

Возвращает точку входа для этой сборки.

 

EscapedCodeBase

Возвращает URI, предоставляющий базовый код, включая

 

escape-знаки.

 

 

 

 

 

 

Evidence

Возвращает свидетельство для этой сборки.

 

 

 

 

FullName

Возвращает отображаемое имя сборки.

 

 

 

GlobalAssemblyCache

Возвращает значение, показывающее, была ли сборка

 

загружена из глобального кэша сборок.

 

 

 

ImageRuntimeVersion

Возвращает версию общеязыковой среды выполнения (CLR),

 

сохраненной в файле, содержащем манифест.

 

Location

Возвращает местонахождение в формате базового кода

 

загруженного

файла, содержащего

манифест,

если для него

 

 

 

 

 

108

 

 

 

 

 

 

 

 

109

 

 

 

 

 

 

 

 

 

 

не было теневого копирования.

 

 

 

Открытые методы

 

 

 

 

 

 

 

CreateInstance

 

Перегружен. Находит тип в этой сборке и создает его

 

 

 

экземпляр, используя абстрактный метод.

 

 

CreateQualifiedName

 

Статический. Создает тип, задаваемый отображаемым

 

 

 

именем его сборки.

 

 

 

 

Equals

(унаследовано

от

Перегружен. Определяет, равны ли два экземпляра Object.

Object)

 

 

 

 

 

 

 

 

 

 

 

GetAssembly

 

Статический. Возвращает сборку, в которой определяется

 

 

 

заданный класс.

 

 

 

 

GetCallingAssembly

 

Статический. Возвращает Assembly метода, который

 

 

 

вызывает текущий метод выполнения.

 

 

 

 

 

 

GetCustomAttributes

 

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

 

 

 

этой сборки.

 

 

 

 

 

GetEntryAssembly

 

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

 

 

 

приложения по умолчанию. В других доменах приложений

 

 

 

это первый исполняемый процесс, который был выполнен

 

 

 

AppDomain.ExecuteAssembly.

 

 

 

 

 

 

 

 

 

 

 

GetExecutingAssembly

 

Статический.

Возвращает

Assembly,

из

которой

 

 

 

исполняется текущий код.

 

 

 

 

GetExportedTypes

 

Возвращает экспортируемые типы, определенные в этой

 

 

 

сборке.

 

 

 

 

 

GetFile

 

 

Возвращает объект FileStream для указанного файла из

 

 

 

таблицы файлов манифеста данной сборки.

 

 

GetFiles

 

 

Перегружен. Возвращает файлы в таблице файлов манифеста

 

 

 

сборки.

 

 

 

 

 

GetHashCode (унаследовано

от

Служит хеш-функцией для конкретного типа, пригоден для

Object)

 

 

использования в алгоритмах хеширования и структурах

 

 

 

данных, например в хеш-таблице.

 

 

 

GetLoadedModules

 

Перегружен.

Возвращает

все

загруженные

модули,

 

 

 

являющиеся частью этой сборки.

 

 

 

 

 

 

GetManifestResourceInfo

 

Возвращает информацию о способе сохранения данного

 

 

 

ресурса.

 

 

 

 

 

GetManifestResourceNames

 

Возвращает имена всех ресурсов в этой сборке.

 

 

 

 

GetManifestResourceStream

 

Перегружен. Загружает указанный ресурс манифеста из

 

 

 

сборки.

 

 

 

 

 

GetModule

 

 

Возвращает указанный модуль этой сборки.

 

 

GetModules

 

 

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

 

 

 

этой сборки.

 

 

 

 

 

 

 

 

 

GetName

 

 

Перегружен. Возвращает AssemblyName для этой сборки.

 

 

 

GetObjectData

 

Возвращает сведения сериализации со всеми данными,

 

 

 

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

 

 

 

GetReferencedAssemblies

 

Возвращает объекты AssemblyName для всех сборок, на

 

 

 

которые ссылается данная сборка.

 

 

 

GetSatelliteAssembly

 

Перегружен. Возвращает сопутствующую сборку.

 

 

 

 

 

GetType

 

 

Перегружен. Возвращает объект Type, предоставляющий

 

 

 

указанный тип.

 

 

 

 

 

GetTypes

 

 

Возвращает типы, определенные в этой сборке.

 

 

 

 

 

IsDefined

 

 

Показывает, определен ли пользовательский атрибут,

 

 

 

заданный указанным значением Type.

 

 

 

Load

 

 

Статический. Перегружен. Загружает сборку.

 

 

 

 

 

LoadFile

 

 

Статический. Перегружен. Загружает содержимое файла

 

 

 

сборки.

 

 

 

 

 

LoadFrom

 

 

Статический. Перегружен. Загружает сборку.

 

 

 

 

 

LoadModule

 

 

Перегружен. Загружает внутренний модуль этой сборки.

 

 

 

LoadWithPartialName

 

Статический. Перегружен. Загружает сборку из папки

 

 

 

приложения или из глобального кэша сборок, используя

 

 

 

частичное имя.

 

 

 

 

 

ToString

 

 

Переопределен. Возвращает полное имя сборки, также

 

 

 

называемое отображаемым именем.

 

 

 

Открытые события

 

 

 

 

 

 

 

ModuleResolve

 

Возникает, когда загрузчик классов общеязыковой среды

 

 

 

выполнения не

может обработать

ссылку

на

внутренний

109

110

 

 

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

Защищенные методы

 

 

Finalize (унаследовано

от

Переопределен. Позволяет объекту Object попытаться

Object)

 

освободить ресурсы и выполнить другие завершающие

 

 

операции, перед тем как объект Object будет уничтожен в

 

 

процессе сборки мусора.

 

 

В языках C# и C++ для функций финализации используется

 

 

синтаксис деструктора.

MemberwiseClone

 

Создает неполную копию текущего Object.

(унаследовано от Object)

 

 

 

 

 

Класс сборки в действии

Исследование свойств и областей применения класса Assembly начинаем с создания тестовой однофайловой сборки AssemblyForStart в рамках проекта Class

Library.

Первая сборка Operators00.exe:

using System; namespace Operators00

{

public class xPoint

{

float x, y; xPoint()

{

x = 0.0F; y = 0.0F;

}

public xPoint(float xKey, float yKey):this()

{

x = xKey; y = yKey;

}

public static bool operator true(xPoint xp)

{

if (xp.x != 0.0F && xp.y != 0.0F) return true; else return false;

}

public static bool operator false(xPoint xp)

{

if (xp.x == 0.0F || xp.y == 0.0F) return false; else return true;

}

public static xPoint operator | (xPoint key1, xPoint key2)

{

if (key1) return key1; if (key2) return key2; return new xPoint();

}

public static xPoint operator & (xPoint key1, xPoint key2)

{

if (key1 && key2) return new xPoint(1.0F, 1.0F); return new xPoint();

}

public void Hello()

{

Console.WriteLine(“Hello! Point {0},{1} is here!”,this.x,this.y);

}

}

110

Соседние файлы в предмете Языки программирования