На этом шаге мы рассмотрим назначение и использование этой инструкции.
Представим себе такую ситуацию. В программе создан объект класса, и у этого объекта есть поле (например, целочисленное). Мы не можем создать указатель для объекта, но можем создать указатель для поля, поскольку фактически это некоторая переменная. Но при этом мы сталкиваемся с потенциальной проблемой. Дело в том, что если в какой-то момент окажется, что в программе ссылок на объект больше нет (а это вполне реальная ситуация), то объект из памяти может быть удален. И тогда указатель будет ссылаться на область памяти, которая больше не используется для хранения значения поля. Такие ситуации считаются (и являются) потенциально опасными. Они блокируются: просто так указатель на поле объекта не создать, приходится использовать "специальный подход".
 То, что на поле объекта ссылается указатель, само по себе не защищает объект от удаления. В расчет принимаются только объектные переменные, которые ссылаются 
на объект. Если таких ссылок нет, объект помещается в очередь на удаление.
 
То, что на поле объекта ссылается указатель, само по себе не защищает объект от удаления. В расчет принимаются только объектные переменные, которые ссылаются 
на объект. Если таких ссылок нет, объект помещается в очередь на удаление.
Для предотвращения удаления (системой сборки мусора) переменных (например, поля объекта), на которые ссылаются указатели, используется инструкция fixed. Шаблон использования этой инструкции представлен ниже:
fixed(тип* указатель = &переменная){ // Команды }
После ключевого слова fixed в круглых скобках объявляется указатель, которому присваивается значение (адрес переменной или поля объекта). Команды, выполняемые с привлечением данного указателя, размещаются в отдельном блоке, выделенном фигурными скобками. Указатель, объявленный в fixed-блоке, доступен только в пределах этого блока. Объект, на поле которого ссылается указатель, не будет удален из памяти до тех пор, пока выполняются команды в fixed-блоке. Программа, в которой иллюстрируется использование инструкции fixed, представлена в примере ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr211_1 { // Класс с полем: class MyClass { // Поле: public int number; // Конструктор: public MyClass(int n) { number = n; } // Деструктор: ~MyClass() { Console.WriteLine("Удален объект с полем " + number); } } // Главный класс программы: class Program { // Главный метод: unsafe static void Main() { // Использован fixed-блок: fixed (int* p = &new MyClass(123).number) { // Отображение значения поля: Console.WriteLine("Значение поля number: " + *p); // Полю присваивается новое значение: *p = 321; // Отображение сообщения: Console.WriteLine("Завершение fixed-блока"); } } } }
Результат выполнения программы такой:

Рис.1. Результат выполнения программы
В программе описывается класс MyClass, у которого есть открытое целочисленное поле number, конструктор с одним аргументом (определяет значение поля), а также деструктор, который при удалении объекта из памяти выводит в консоль соответствующее сообщение со значением поля number удаляемого объекта.
Главный метод состоит из fixed-блока, в котором объявлен указатель p на целочисленное значение, и этому указателю в качестве значения присвоено выражение &new MyClass(123).number. Проанализируем его. Инструкция new MyClass(123) создает объект класса MyClass, и поле number этого объекта равно 123. Значением инструкции является ссылка на созданный объект. Эта ссылка никуда не записывается, и поэтому объект является анонимным. Сразу после создания он попадает в очередь на удаление. Точнее, должен был бы попасть. Инструкцией new MyClass(123).number мы обращаемся к полю number этого объекта, а символ & перед всем выражением означает, что нас интересует адрес этого поля. Таким образом, значением выражения &new MyClass(123).number является адрес поля number созданного анонимного объекта, и этот адрес записывается в указатель p. В итоге объект, хотя он и анонимный, гарантированно не удаляется из памяти, пока выполняется fixed-блок.
Значение поля объекта проверяем с использованием выражения *p. Командой
*p = 321;
На следующем шаге мы рассмотрим связь указателей и массивов.