Чтение онлайн

на главную - закладки

Жанры

Полное руководство. С# 4.0
Шрифт:

} В данном примере поле MyClass.SIZE инициализируется значением 10. После этого его можно использовать, но не изменять. Для того чтобы убедиться в этом, уда лите символы комментария в начале последней строки приведенного выше кода и по пробуйте скомпилировать его. В итоге вы получите сообщение об ошибке. ### Ключевые слова const и volatile Ключевое слово, или модификатор, const служит для объявления полей и локаль ных переменных, которые нельзя изменять. Исходные значения таких полей и пере менных должны устанавливаться при их объявлении. Следовательно, переменная с модификатором const, по существу, является константой. Например, в следующей строке кода:

const int i = 10; создается переменная i типа const и устанавливается ее значение 10. Поле типа const очень похоже на поле типа readonly, но все же между ними есть отличие. Если поле типа readonly можно устанавливать

в конструкторе, то поле типа const — нельзя. Ключевое слово, или модификатор, volatile уведомляет компилятор о том, что значение поля может быть изменено двумя или более параллельно выполняющимися потоками. В этой ситуации одному потоку может быть неизвестно, когда поле было изменено другим потоком. И это очень важно, поскольку компилятор C# будет автома тически выполнять определенную оптимизацию, которая будет иметь результат лишь в том случае, если поле доступно только одному потоку. Для того чтобы подобной оптимизации не подвергалось общедоступное поле, оно объявляется как volatile. Этим компилятор уведомляется о том, что значение поля типа volatile следует по лучать всякий раз, когда к нему осуществляется доступ. ### Оператор using Помимо рассматривавшейся ранее директивы using, имеется вторая форма ключе вого слова using в виде оператора. Ниже приведены две общие формы этого оператора:

using (obj) { // использовать объект obj }

using (тип obj = инициализатор) { // использовать объект obj } где obj является выражением, в результате вычисления которого должен быть полу чен объект, реализующий интерфейс System.IDisposable. Этот объект определяет переменную, которая будет использоваться в блоке оператора using. В первой форме объект объявляется вне оператора using, а во второй форме — в этом операторе. По завершении блока оператора using для объекта obj вызывается метод Dispose, определенный в интерфейсе System.IDisposable. Таким образом, оператор using предоставляет средства, необходимые для автоматической утилизации объектов, когда они больше не нужны. Не следует, однако, забывать, что оператор using применяется только к объектам, реализующим интерфейс System.IDisposable. В приведенном ниже примере демонстрируются обе формы оператора using.

// Продемонстрировать применение оператора using. using System; using System.IO;

class UsingDemo { static void Main { try { StreamReader sr = new StreamReader("test.txt"); // Использовать объект в операторе using. using(sr) { // ... } } catch(IOException exc) { // ... } try { // Создать объект класса StreamReader в операторе using. using(StreamReader sr2 = new StreamReader("test.txt")) { // ... } } catch(IOException exc) { // ... } }

} В данном примере интерфейс IDisposable реализуется в классе StreamReader (посредством его базового класса TextReader). Поэтому он может использоваться в операторе using. По завершении этого оператора автоматически вызывается метод Dispose для переменной потока, закрывая тем самым поток. Как следует из приведенного выше примера, оператор using особенно полезен для работы с файлами, поскольку файл автоматически закрывается по завершении блока этого оператора, даже если он и завершается исключением. Таким образом, закрытие файла с помощью оператора using зачастую упрощает код обработки файлов. Разу меется, применение оператора using не ограничивается только работой с файлами. В среде .NET Framework имеется немало других ресурсов, реализующих интерфейс IDisposable. И всеми этими ресурсами можно управлять с помощью оператора using. ### Ключевое слово extern Ключевое слово extern находит два основных применения. Каждое из них рассма тривается далее по порядку. #### Объявление внешних методов В первом своем применении ключевое слово extern было доступно с момента соз дания С#. Оно обозначает, что метод предоставляется в неуправляемом коде, который не является составной частью программы. Иными словами, метод предоставляется внешним кодом. Для того чтобы объявить метод как внешний, достаточно указать в самом начале его объявления модификатор extern. Таким образом, общая форма объявления внешне го метода выглядит следующим образом.

extern возвращаемыйтип имяметода(список_аргументов); Обратите внимание на отсутствие фигурных скобок. В данном варианте ключевое слово extern нередко применяется вместе с атри бутом DllImport, обозначающим библиотеку DLL, в которой содержится внешний метод. Атрибут DllImport принадлежит пространству имен System.Runtime. InteropServices. Он допускает несколько вариантов, но, как правило, достаточно указать лишь имя библиотеки DLL, в которой

содержится внешний метод. Вообще го воря, внешние методы следует программировать на С. (Если же это делается на С++, то имя внешнего метода может быть изменено в библиотеке DLL путем дополнительного оформления типов.) Для того чтобы стало понятнее, как пользоваться внешними методами, обратимся к примеру конкретной программы, состоящей из двух файлов. Ниже приведен ис ходный код С из первого файла ExtMeth.с, где определяется метод AbsMax. include

int __declspec(dllexport) AbsMax(int a, int b) { return abs(a) < abs(b) ? abs(b) : abs(a); } В методе AbsMax сравниваются абсолютные значения двух его параме тров и возвращается самое большое из них. Обратите внимание на обозначение _ declspec(dllexport). Это специальное расширение языка С для программных средств корпорации Microsoft. Оно уведомляет компилятор о необходимости экспор тировать метод AbsMax из библиотеки DLL, в которой он содержится. Для компи лирования файла ExtMeth.с в командной строке указывается следующее.

CL /LD /MD ExtMeth.с В итоге создается библиотечный файл DLL — ExtMeth.dll. Далее следует программа на С#, в которой применяется внешний метод AbsMax.

using System; using System.Runtime.InteropServices;

class ExternMeth { // Здесь объявляется внешний метод. [DllImport("ExtMeth.dll")] public extern static int AbsMax(int a, int b); static void Main { // Использовать внешний метод. int max = AbsMax(-10, —20); Console.WriteLine(max); }

} Обратите внимание на использование атрибута DllImport в приведенной выше программе. Он уведомляет компилятор о наличии библиотеки DLL, содержащей внешний метод AbsMax. В данном случае это файл ExtMeth.dll, созданный во вре мя компиляции файла с исходным текстом метода AbsMax на С. В результате вы полнения данной программы на экран, как и ожидалось, выводится значение 20. #### Объявление псевдонима внешней сборки Во втором применении ключевое слово extern предоставляет псевдоним для внешней сборки, что полезно в тех случаях, когда в состав программы включаются две отдельные сборки с одним и тем же именем элемента. Так, если в сборке test1 содер жится класс MyClass, а в сборке test2 класс с таким же именем, то при обращении к классу по этому имени в одной и той же программе может возникнуть конфликт. Для разрешения подобного конфликта необходимо создать псевдоним каждой сборки. Это делается в два этапа. На первом этапе нужно указать псевдонимы, исполь зуя параметр компилятора /r, как в приведенном ниже примере.

/r:Asm1=test1 /r:Asm2=test2 А на втором этапе необходимо ввести операторы с ключевым словом extern, в ко торых делается ссылка на указанные выше псевдонимы. Ниже приведена форма такого оператора для создания псевдонима сборки.

extern alias имя_сборки; Если продолжить приведенный выше пример, то в программе должны появиться следующие строки кода.

extern alias Asm1; extern alias Asm2; Теперь оба варианта класса MyClass будут доступны в программе по соответствую щему псевдониму. Рассмотрим полноценный пример программы, в которой демонстрируется приме нение внешних псевдонимов. Эта программа состоит из трех файлов. Ниже приведен исходный текст, который следует поместить в первый файл — test1.cs.

using System;

namespace MyNS { public class MyClass { public MyClass { Console.WriteLine("Конструирование из файла MyClass1.dll."); } } } Далее следует исходный текст из файла test2.cs.

using System;

namespace MyNS { public class MyClass { public MyClass { Console.WriteLine("Конструирование из файла MyClass2.dll."); } } } Обратите внимание на то, что в обоих файлах, test1.cs и test2.cs, объявляется пространство имен MyNS и что именно в этом пространстве в обоих файлах опреде ляется класс MyClass. Следовательно, без псевдонима оба варианта класса MyClass будут недоступными ни одной из программ. И наконец, ниже приведен исходный текст из третьего файла test3.cs, где ис пользуются оба варианта класса MyClass из файлов test1.cs и test2.cs. Это стано вится возможным благодаря операторам с внешними псевдонимами.

// Операторы с внешними псевдонимами должны быть указаны в самом начале файла. extern alias Asm1; extern alias Asm2; using System;

class Demo { static void Main { Asm1::MyNS.MyClass t = new Asm1::MyNS.MyClass; Asm2::MyNS.MyClass t2 = new Asm2::MyNS.MyClass; } } Сначала следует скомпилировать файлы test1.cs и test2.cs в их библиотечные эквиваленты DLL. Для этого достаточно ввести в командной строке следующее.

csc /t:library test1.cs csc /t:library test2.cs Затем необходимо скомпилировать файл test3.cs, указав в командной строке

Поделиться:
Популярные книги

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9