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

на главную

Жанры

C# для профессионалов. Том II

Ватсон Карли

Шрифт:

int X = 10, Y = 20;

int *рХ = &Х;

*рХ = 30;

pХ = &Y;

++рХ; // добавляет sizeof(int) к рХ

Отметим, однако, следующие моменты.

□ В C# не допускается разыменовывать указатели

void*
, также нельзя выполнять арифметические операции над указателями
void*
. Синтаксис указателя
void*
был сохранен для обратной совместимости, для вызова внешних функций API, которые не знают о .NET и которые требуют указателей
void*
в качестве параметров.

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

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

/unsafe
при компиляции кода, который содержит указатели.

□ Указатели не могут указывать на переменные, которые встроены в ссылочные типы данных (например, членов класса), если только они не объявлены внутри инструкции

fixed
.

Фиксация донных в куче

Разрешается присвоить адрес типа данных значения указателю, даже если этот тип встроен как поле-член в ссылочный тип данных. Однако такой указатель должен быть объявлен внутри инструкции

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

class MyClass {

 public int X; // и т.д.

}

// где-то в другом месте кода

MyClass Mine = new MyClass; // выполнить обработку

fixed (int *pX = Mine.X) {

 // можно использовать рХ в этом блоке

}

Возможно вкладывание блоков

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

fixed (int *рХ = Mine.X, *рХ2 = Mine2.X) {

Объявление массивов в стеке

C# предоставляет оператор

stackalloc
, который используется в соединении с указателями для объявления массива в стеке без накладных расходов. Массив, размещаемый таким образом, не является полным объектом
System.Array
в стиле C#, он является просто массивом чисел, аналогичным одномерному массиву C++. Элементы этого массива не инициализируются и доступны с помощью
такого же синтаксиса, как и в C++, с использованием квадратных скобок для указателя.

Оператор

stackalloc
требует спецификации типа данных и числа размещаемых элементов.

Синтаксис C++:

unsigned long рМуArray[20];

Синтаксис C#:

ulong *pMyArray = stackalloc ulong[20];

Отметим, однако, что хотя эти массивы похожи, версия C# позволяет определить размер во время выполнения:

int X;

// инициализировать X

ulong *pMyArray = stackalloc ulong[X];

Интерфейсы

Интерфейсы являются особенностью C#, которая не имеет аналога в ANSI C++, хотя компания Microsoft ввела интерфейсы в C++ с помощью специального ключевого слова. Идея интерфейса развилась из интерфейсов COM, которые предназначены служить контрактом, который указывает, какие методы или свойства реализует объект.

Интерфейс в C# не совсем такой, как интерфейс COM, так как он не имеет связанного с ним GUID, не является производным из

IUnknown
и не имеет связанных с ним записей в реестре (хотя можно отобразить интерфейс C# на интерфейс COM). Интерфейс C# является просто множеством определений функций и свойств. Он может рассматриваться как аналог абстрактного класса и определяется с помощью синтаксиса аналогичного класса.

interface IMyInterface {

 void MyMethod(int X);

}

Можно заметить, однако, следующие синтаксические различия с определением класса:

□ Методы не имеют модификаторов доступа.

□ Методы никогда не реализуются в интерфейсе.

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

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

class MyClass : MyBaseClass, IMyInterface, IAnotherInterface // и т.д.

{

 public virtual void MyMethod(int X) {

// реализация

 }

 // и т.д.

В этом примере выбрана реализация

MyMethod
как виртуального метода с открытым доступом.

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

interface IMyInterface : IBaseInterface

Можно проверить, что объект реализует интерфейс, используя либо оператор

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

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

Охотник за головами

Вайс Александр
1. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Охотник за головами

Кодекс Охотника. Книга XXIII

Винокуров Юрий
23. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXIII

Раб и солдат

Greko
1. Штык и кинжал
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Раб и солдат

Без Чести

Щукин Иван
4. Жизни Архимага
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Без Чести

Убивать чтобы жить 3

Бор Жорж
3. УЧЖ
Фантастика:
героическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Убивать чтобы жить 3

На границе империй. Том 4

INDIGO
4. Фортуна дама переменчивая
Фантастика:
космическая фантастика
6.00
рейтинг книги
На границе империй. Том 4

Бестужев. Служба Государевой Безопасности. Книга вторая

Измайлов Сергей
2. Граф Бестужев
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бестужев. Служба Государевой Безопасности. Книга вторая

Строгий Режим

Тесленок Кирилл Геннадьевич
3. Гарем вне закона
Фантастика:
фэнтези
юмористическая фантастика
5.45
рейтинг книги
Строгий Режим

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Боги, пиво и дурак. Том 3

Горина Юлия Николаевна
3. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 3

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

Сапфир Олег
24. Лекарь
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Идеальный мир для Лекаря 24

Дайте поспать!

Матисов Павел
1. Вечный Сон
Фантастика:
юмористическое фэнтези
постапокалипсис
рпг
5.00
рейтинг книги
Дайте поспать!

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник