Для установки этого свойства в Visual Studio предлагается графический пользовательский интерфейс. Откройте окно свойств проекта. В раскрывающемся списке Configuration (Конфигурация) выберите вариант All Configurations (Все конфигурации), перейдите на вкладку Build (Сборка) и отметьте флажок Allow unsafe code (Разрешить небезопасный код), как показано на рис. 11.1.

<p id="AutBody_Root436">Ключевое слово unsafe</p>

Для работы с указателями в C# должен быть специально объявлен блок "небезопасного кода" с использованием ключевого слова unsafe (любой код, который не помечен ключевым словом unsafe, автоматически считается "безопасным"). Например, в следующем файле Program.cs объявляется область небезопасного кода внутри операторов верхнего уровня:

using System;

using UnsafeCode;

Console.WriteLine("***** Calling method with unsafe code *****");

unsafe

{

  // Здесь работаем с указателями!

}

// Здесь работа с указателями невозможна!

В дополнение к объявлению области небезопасного кода внутри метода можно строить "небезопасные" структуры, классы, члены типов и параметры. Ниже приведено несколько примеров (типы Node и Node2 в текущем проекте определять не нужно):

// Эта структура целиком является небезопасной и может

// использоваться только в небезопасном контексте.

unsafe struct Node

{

  public int Value;

  public Node* Left;

  public Node* Right;

}

// Эта структура безопасна, но члены Node2* - нет.

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

// обращаться к Value, но не к Left и Right.

public struct Node2

{

  public int Value;

  // Эти члены доступны только в небезопасном контексте!

  public unsafe Node2* Left;

  public unsafe Node2* Right;

}

Методы (статические либо уровня экземпляра) также могут быть помечены как небезопасные. Предположим, что какой-то статический метод будет использовать логику указателей. Чтобы обеспечить возможность вызова данного метода только из небезопасного контекста, его можно определить так:

static unsafe void SquareIntPointer(int* myIntPointer)

{

  // Возвести значение в квадрат просто для тестирования.

  *myIntPointer *= *myIntPointer;

}

Конфигурация метода требует, чтобы вызывающий код обращался к методу SquareIntPointer() следующим образом:

unsafe

{

  int myInt = 10;

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

  SquareIntPointer(&myInt);

  Console.WriteLine("myInt: {0}", myInt);

}

int myInt2 = 5;

// Ошибка на этапе компиляции!

// Это должно делаться в небезопасном контексте!

SquareIntPointer(&myInt2);

Console.WriteLine("myInt: {0}", myInt2);

Если вы не хотите вынуждать вызывающий код помещать такой вызов внутрь небезопасного контекста, то можете поместить все операторы верхнего уровня в блок unsafe. При использовании в качестве точки входа метода Main() можете пометить Main() ключевым словом unsafe. В таком случае приведенный ниже код скомпилируется:

static unsafe void Main(string[] args)

{

  int myInt2 = 5;

  SquareIntPointer(&myInt2);

  Console.WriteLine("myInt: {0}", myInt2);

}

Запустив такую версию кода, вы получите следующий вывод:

myInt: 25

На заметку! Важно отметить, что термин "небезопасный" был выбран небезосновательно. Прямой доступ к стеку и работа с указателями может приводить к неожиданным проблемам с вашим приложением, а также с компьютером, на котором оно функционирует. Если вам приходится иметь дело с небезопасным кодом, тогда будьте крайне внимательны.

<p id="AutBody_Root437">Работа с операциями * и &</p>
Перейти на страницу:

Похожие книги