fixed — Instrukcja (odwołanie w C#)fixed Statement (C# Reference)

fixed Instrukcja zapobiega ponownemu lokalizowaniu ruchomej zmiennej przez moduł wyrzucania elementów bezużytecznych.The fixed statement prevents the garbage collector from relocating a movable variable. Instrukcja jest dozwolona tylko w niebezpiecznym kontekście. niebezpieczny fixedThe fixed statement is only permitted in an unsafe context. Możesz również użyć słowa kluczowego, fixed aby utworzyć bufory o ustalonym rozmiarze.You can also use the fixed keyword to create fixed size buffers.

fixed Instrukcja ustawia wskaźnik na zmienną zarządzaną i "pinezki", która jest zmienna podczas wykonywania instrukcji.The fixed statement sets a pointer to a managed variable and "pins" that variable during the execution of the statement. Wskaźniki do ruchomych zmiennych zarządzanych są przydatne tylko w fixed kontekście.Pointers to movable managed variables are useful only in a fixed context. fixed Bez kontekstu, wyrzucanie elementów bezużytecznych może przewidzieć nieprzewidywalne zmienne.Without a fixed context, garbage collection could relocate the variables unpredictably. C# Kompilator umożliwia tylko przypisanie wskaźnika do zmiennej zarządzanej w fixed instrukcji.The C# compiler only lets you assign a pointer to a managed variable in a fixed statement.

class Point 
{ 
    public int x;
    public int y; 
}

unsafe private static void ModifyFixedStorage()
{
    // Variable pt is a managed variable, subject to garbage collection.
    Point pt = new Point();

    // Using fixed allows the address of pt members to be taken,
    // and "pins" pt so that it is not relocated.

    fixed (int* p = &pt.x)
    {
        *p = 1;
    }
}

Wskaźnik można zainicjować za pomocą tablicy, ciągu, buforu o ustalonym rozmiarze lub adresu zmiennej.You can initialize a pointer by using an array, a string, a fixed-size buffer, or the address of a variable. Poniższy przykład ilustruje użycie adresów zmiennych, tablic i ciągów:The following example illustrates the use of variable addresses, arrays, and strings:

Point point = new Point();
double[] arr = { 0, 1.5, 2.3, 3.4, 4.0, 5.9 };
string str = "Hello World";

// The following two assignments are equivalent. Each assigns the address
// of the first element in array arr to pointer p.

// You can initialize a pointer by using an array.
fixed (double* p = arr) { /*...*/ }

// You can initialize a pointer by using the address of a variable. 
fixed (double* p = &arr[0]) { /*...*/ }

// The following assignment initializes p by using a string.
fixed (char* p = str) { /*...*/ }

// The following assignment is not valid, because str[0] is a char, 
// which is a value, not a variable.
//fixed (char* p = &str[0]) { /*...*/ } 

Począwszy od C# 7,3, fixed instrukcja działa na dodatkowych typach poza tablicami, ciągami, buforami o stałym rozmiarze lub zmiennymi niezarządzanymi.Starting with C# 7.3, the fixed statement operates on additional types beyond arrays, strings, fixed size buffers, or unmanaged variables. Każdy typ, który implementuje metodę o GetPinnableReference nazwie, może być przypięty.Any type that implements a method named GetPinnableReference can be pinned. Musi zwracać zmienną typu niezarządzanego. Cómo se pronuncia typ niezarządzany GetPinnableReference refThe GetPinnableReference must return a ref variable of an unmanaged type. Typy System.Span<T> .NET i System.ReadOnlySpan<T> wprowadzone w środowisku .NET Core 2,0 używają tego wzorca i mogą być przypięte.The .NET types System.Span<T> and System.ReadOnlySpan<T> introduced in .NET Core 2.0 make use of this pattern and can be pinned. Jest to pokazane w poniższym przykładzie:This is shown in the following example:

unsafe private static void FixedSpanExample()
{
    int[] PascalsTriangle = {
                  1,
                1,  1,
              1,  2,  1,
            1,  3,  3,  1,
          1,  4,  6,  4,  1,
        1,  5,  10, 10, 5,  1
    };

    Span<int> RowFive = new Span<int>(PascalsTriangle, 10, 5);

    fixed (int* ptrToRow = RowFive)
    {
        // Sum the numbers 1,4,6,4,1
        var sum = 0;
        for (int i = 0; i < RowFive.Length; i++)
        {
            sum += *(ptrToRow + i);
        }
        Console.WriteLine(sum);
    }
}

Jeśli tworzysz typy, które powinny wchodzić w skład tego wzorca, zobacz Span<T>.GetPinnableReference() , aby zapoznać się z przykładem implementacji wzorca.If you are creating types that should participate in this pattern, see Span<T>.GetPinnableReference() for an example of implementing the pattern.

W jednej instrukcji można zainicjować wiele wskaźników, jeśli są one tego samego typu:Multiple pointers can be initialized in one statement if they are all the same type:

fixed (byte* ps = srcarray, pd = dstarray) {...}

Aby zainicjować wskaźniki różnych typów, należy po prostu fixed zagnieżdżać instrukcje, jak pokazano w poniższym przykładzie.To initialize pointers of different types, simply nest fixed statements, as shown in the following example.

fixed (int* p1 = &point.x)
{
    fixed (double* p2 = &arr[5])
    {
        // Do something with p1 and p2.
    }
}

Po wykonaniu kodu w instrukcji wszystkie przypięte zmienne są odpięte i podlegają wyrzucaniu elementów bezużytecznych.After the code in the statement is executed, any pinned variables are unpinned and subject to garbage collection. W związku z tym nie należy wskazywać na te fixed zmienne poza instrukcją.Therefore, do not point to those variables outside the fixed statement. Zmienne zadeklarowane w fixed instrukcji należą do zakresu tej instrukcji, ułatwiając to:The variables declared in the fixed statement are scoped to that statement, making this easier:

fixed (byte* ps = srcarray, pd = dstarray)
{
   ...
}
// ps and pd are no longer in scope here.

Wskaźniki inicjowane fixed w instrukcjach są zmiennymi tylko do odczytu.Pointers initialized in fixed statements are readonly variables. Jeśli chcesz zmodyfikować wartość wskaźnika, należy zadeklarować drugą zmienną wskaźnika i zmodyfikować ją.If you want to modify the pointer value, you must declare a second pointer variable, and modify that. Nie można zmodyfikować zmiennej zadeklarowanej w fixed instrukcji:The variable declared in the fixed statement cannot be modified:

fixed (byte* ps = srcarray, pd = dstarray)
{
    byte* pSourceCopy = ps;
    pSourceCopy++; // point to the next element.
    ps++; // invalid: cannot modify ps, as it is declared in the fixed statement.
}

Możesz przydzielić pamięć na stosie, gdzie nie podlega wyrzucaniu elementów bezużytecznych i dlatego nie musi być przypięty.You can allocate memory on the stack, where it is not subject to garbage collection and therefore does not need to be pinned. W tym celu należy użyć stackalloc operatora.To do that use the stackalloc operator.

specyfikacja języka C#C# language specification

Aby uzyskać więcej informacji, zobacz sekcję FIXED Statement w C# specyfikacji języka.For more information, see The fixed statement section of the C# language specification.

Zobacz takżeSee also