KnigaRead.com/
KnigaRead.com » Разная литература » Прочее » Герберт Шилдт - C# 4.0 полное руководство - 2011

Герберт Шилдт - C# 4.0 полное руководство - 2011

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн "Герберт Шилдт - C# 4.0 полное руководство - 2011". Жанр: Прочее издательство неизвестно, год неизвестен.
Перейти на страницу:

Ключевые слова 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.10;

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) {

// ...

В данном примере интерфейс I Disposable реализуется в классе StreamReader (посредством его базового класса TextReader). Поэтому он может использоваться в операторе using. По завершении этого оператора автоматически вызывается метод Dispose () для переменной потока, закрывая тем самым поток.

Как следует из приведенного выше примера, оператор using особенно полезен для работы с файлами, поскольку файл автоматически закрывается по завершении блока этого оператора, даже если он и завершается исключением. Таким образом, закрытие файла с помощью оператора using зачастую упрощает код обработки файлов. Разумеется, применение оператора using не ограничивается только работой с файлами. В среде .NET Framework имеется немало других ресурсов, реализующих интерфейс I Disposable. И всеми этими ресурсами можно управлять с помощью оператора using.

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

Ключевое слово extern находит два основных применения. Каждое из них рассматривается далее по порядку.

Объявление внешних методов

В первом своем применении ключевое слово extern было доступно с момента создания С#. Оно обозначает, что метод предоставляется в неуправляемом коде, который не является составной частью программы. Иными словами, метод предоставляется внешним кодом.

Для того чтобы объявить метод как внешний, достаточно указать в самом начале его объявления модификатор extern. Таким образом, общая форма объявления внешнего метода выглядит следующим образом.

extern возвращаемый_тип имя_метода (список_аргументов) ;

Обратите внимание на отсутствие фигурных скобок.

В данном варианте ключевое слово extern нередко применяется вместе с атрибутом Dll Import, обозначающим библиотеку DLL, в которой содержится внешний метод. Атрибут Dll Import принадлежит пространству имен System. Runtime . Inter op Services. Он допускает несколько вариантов, но, как правило, достаточно указать лишь имя библиотеки DLL, в которой содержится внешний метод. Вообще говоря, внешние методы следует программировать на С. (Если же это делается на C++, то имя внешнего метода может быть изменено в библиотеке DLL путем дополнительного оформления типов.)

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

#include <stdlib.h>

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 {

// Здесь объявляется внешний метод.

[Dlllmport("ExtMeth.dll")]

public extern static int AbsMax(int a, int b);

static void Main() {

// Использовать внешний метод, int max = AbsMax(-10, -20);

Console.WriteLine(max);

}

}

Обратите внимание на использование атрибута Dlllmport в приведенной выше программе. Он уведомляет компилятор о наличии библиотеки DLL, содержащей внешний метод AbsMax (). В данном случае это файл ExtMeth. dll, созданный во время компиляции файла с исходным текстом метода AbsMax () на С. В результате выполнения данной программы на экран, как и ожидалось, выводится значение 20.

Объявление псевдонима внешней сборки

Во втором применении ключевое слово extern предоставляет псевдоним для внешней сборки, что полезно в тех случаях, когда в состав программы включаются две отдельные сборки с одним и тем же именем элемента. Так, если в сборке testl содержится класс MyClass, а в сборке test2 класс с таким же именем, то при обращении к классу по этому имени в одной и той же программе может возникнуть конфликт.

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

/г:Asml=testl /г:Asm2=test2

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

extern alias имя_сборки;

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

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*