Для установки этого свойства в Visual Studio предлагается графический пользовательский интерфейс. Откройте окно свойств проекта. В раскрывающемся списке Configuration
(Конфигурация) выберите вариант All Configurations (Все конфигурации), перейдите на вкладку Build (Сборка) и отметьте флажок Allow unsafe code (Разрешить небезопасный код), как показано на рис. 11.1.Ключевое слово unsafe
Для работы с указателями в 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
{
// Возвести значение в квадрат просто для тестирования.
*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
На заметку!
Важно отметить, что термин "небезопасный" был выбран небезосновательно. Прямой доступ к стеку и работа с указателями может приводить к неожиданным проблемам с вашим приложением, а также с компьютером, на котором оно функционирует. Если вам приходится иметь дело с небезопасным кодом, тогда будьте крайне внимательны.Работа с операциями * и &