fixed-Anweisung (C#-Referenz)fixed Statement (C# Reference)

Die fixed-Anweisung verhindert, dass der Garbage Collector eine bewegliche Variable verschiebt.The fixed statement prevents the garbage collector from relocating a movable variable. Die fixed-Anweisung ist nur in einem unsicheren (unsafe) Kontext zulässig.The fixed statement is only permitted in an unsafe context. fixed kann auch zum Erstellen eines Puffers fester Größe verwendet werden.fixed can also be used to create fixed size buffers.

Die fixed-Anweisung setzt einen Zeiger auf eine verwaltete Variable und „fixiert“ diese Variable während der Ausführung der Anweisung.The fixed statement sets a pointer to a managed variable and "pins" that variable during the execution of the statement. Zeiger auf verschiebbare verwaltete Variablen sind nur in einem fixed-Kontext nützlich.Pointers to movable managed variables are useful only in a fixed context. Ohne den fixed-Kontext könnte die automatische Speicherbereinigung die Variablen auf unvorhersehbare Weise verschieben.Without a fixed context, garbage collection could relocate the variables unpredictably. Mit dem C#-Compiler können Sie einer verwalteten Variablen nur in einer fixed-Anweisung einen Zeiger zuweisen.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;
    }
}

Sie können einen Zeiger mit einem Array, einer Zeichenfolge, einem Puffer fester Größe oder der Adresse einer Variablen initialisieren.You can initialize a pointer by using an array, a string, a fixed-size buffer, or the address of a variable. Im folgenden Beispiel wird die Verwendung von Adressen, Arrays und Zeichenfolgen von Variablen veranschaulicht.The following example illustrates the use of variable addresses, arrays, and strings. Weitere Informationen zu Puffern fester Größe finden Sie unter Puffer fester Größe.For more information about fixed-size buffers, see Fixed Size Buffers.

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]) { /*...*/ } 

Ab C# 7.3 funktioniert die fixed-Anweisung mit weiteren Typen, nicht nur mit Arrays, Zeichenfolgen, Puffern mit festgelegter Größe und nicht verwalteten Variablen.Starting with C# 7.3, the fixed statement operates on additional types beyond arrays, strings, fixed-size buffers, or unmanaged variables. Jeder Typ, der eine Methode mit dem Namen GetPinnableReference implementiert, kann angeheftet werden.Any type that implements a method named GetPinnableReference can be pinned. GetPinnableReference muss eine ref-Variable an einen nicht verwalteten Typ zurückgeben.The GetPinnableReference must return a ref variable to an unmanaged type. Weitere Informationen erhalten Sie im Artikel zu Zeigertypen.See the topic on pointer types for more information. Die .NET-Typen System.Span<T> und System.ReadOnlySpan<T>, die in .NET Core 2.0 eingeführt wurden, verwenden dieses Muster und können angeheftet werden.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. Dies wird im folgenden Beispiel gezeigt: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);
    }
}

Wenn Sie Typen erstellen, die auch dieses Muster verwenden sollen, finden Sie unter Span<T>.GetPinnableReference() ein Beispiel für die Implementierung des Musters.If you are creating types that should participate in this pattern, see Span<T>.GetPinnableReference() for an example of implementing the pattern.

Wenn mehrere Zeiger vom selben Typ sind, können sie in einer gemeinsamen Anweisung initialisiert werden:Multiple pointers can be initialized in one statement if they are all the same type:

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

Um Zeiger verschiedener Typen zu initialisieren, schachteln Sie einfach fixed-Anweisungen, wie im folgenden Beispiel gezeigt.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.
    }
}

Nachdem der Code in der Anweisung ausgeführt wird, können beliebige fixierte Variablen gelöst und an die automatische Speicherbereinigung übergeben werden.After the code in the statement is executed, any pinned variables are unpinned and subject to garbage collection. Aus diesem Grund sollten Sie nicht außerhalb der fixed-Anweisung auf diese Variablen verweisen.Therefore, do not point to those variables outside the fixed statement. Die in der fixed-Anweisung deklarierten Variablen beziehen sich auf diese Anweisung. Dadurch wird Folgendes vereinfacht: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.

Bei Zeigern, die in fixed-Anweisungen initialisiert werden, handelt es sich um readonly-Variablen.Pointers initialized in fixed statements are readonly variables. Wenn Sie den Zeigerwert ändern möchten, müssen Sie eine zweite Zeigervariable deklarieren und diese ändern.If you want to modify the pointer value, you must declare a second pointer variable, and modify that. Die in der fixed-Anweisung deklarierte Variable kann nicht verändert werden: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.
}

Im nicht sicheren Modus können Sie dem Stapel Arbeitsspeicher zuweisen, auf dem der Speicher nicht automatisch bereinigt wird und daher nicht fixiert werden muss.In unsafe mode, you can allocate memory on the stack, where it is not subject to garbage collection and therefore does not need to be pinned. Weitere Informationen finden Sie unter stackalloc.For more information, see stackalloc.

// Unsafe method: takes a pointer to an int.
unsafe static void SquarePtrParam(int* p)
{
    *p *= *p;
}

unsafe static void SquarePointValue()
{
    Point pt = new Point
    {
        x = 5,
        y = 6
    };
    // Pin pt in place:
    fixed (int* p = &pt.x)
    {
        SquarePtrParam(p);
    }
    // pt now unpinned.
    Console.WriteLine("{0} {1}", pt.x, pt.y);
    /*
    Output:
    25 6
     */
}

C#-ProgrammiersprachenspezifikationC# Language Specification

Weitere Informationen erhalten Sie unter C#-Sprachspezifikation.For more information, see the C# Language Specification. Die Sprachspezifikation ist die verbindliche Quelle für die Syntax und Verwendung von C#.The language specification is the definitive source for C# syntax and usage.

Siehe auchSee Also

C#-ReferenzC# Reference
C#-ProgrammierhandbuchC# Programming Guide
C#-SchlüsselwörterC# Keywords
unsafeunsafe
Puffer fester GrößeFixed Size Buffers