Поиск

Оператор fixed

Синтаксис оператора fixed таков:

fixed (тип* указатель = выражение) оператор

Как сказано выше, этот оператор говорит GC, чтобы тот не трогал заданную переменную. Заметьте: тип — это неуправляемый тип или void,

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

using System;
class Foo {
public int x; }
class FixedlApp {
unsafe static void SetFooValue(int* x)
{
Console.WriteLineC'Dereferenced pointer to
modify foo.x"); *x = 42; }
unsafe static void Main() {
// Создаем экземпляр структуры.
Console.WriteLine("Creating the Foo class");
Foo foo = new Foo();
Console.WriteLineC'foo.x intialized to {0}", foo.x);

// Оператор fixed фиксирует объект foo в пределах // включающего его составного оператора. Console.Writel_ine("Setting pointer to foo.x"); // Присвоить Foo* адрес объекта foo. fixed(int* f = &foo.x) <

Console.WriteLine("Calling SetFooValue
passing " + "pointer to foo.x");
SetFooValue(f); >
// Убедимся, что мы действительно изменили член через
// указатель на него.
Console.WriteLine("After return from " +
"SetFooValue, foo.x = {0}", foo.x); } >

Этот код создает экземпляр класса Foo и фиксирует его оператором fixed, присваивая адрес его первого члена переменной типа int* (этот тип требуется методу SetFooValue). Заметьте, что оператор fixed включает именно тот код, на котором отразятся изменения при сдвиге объекта Foo сборщиком мусора. Это тонкий, но важный вопрос, касающийся больших и дольше исполняемых блоков кода, для которых вы хотите свести к минимуму время, в течение которого объект будет зафиксирован. В результате компиляции и запуска этого кода вы получите:

Creating the Foo class foo.x intialized to 0 Setting pointer to foo.x
Calling SetFooValue passing pointer to foo.x Dereferenced pointer to
modify foo.x After return from SetFooValue, foo.x = 42

ПРИМЕЧАНИЕ Компилятор С# не ограничивает доступ к фиксированной переменной областью видимости небезопасного кода. Например, вы можете использовать фиксированную переменную как г- value для /-value, определенному в более широкой области видимости, чем область видимости небезопасного блока. В результате может получиться небезопасное значение, применяемое вне небезопасного блока. В этом случае компилятор не выдает предупреждений, а ответственность за соблюдение осторожности при использовании фиксированных переменных в качестве r-value ложится на разработчика.