共用方式為


fixed 語句 - 釘選指標作業的變數

fixed語句可防止垃圾收集行程重新放置可移動的變數,並宣告該變數的指標。 固定或固定變數的位址不會在語句執行期間變更。 您只能在對應的 fixed 語句內使用宣告的指標。 宣告的指標是唯讀的,無法修改:

unsafe
{
    byte[] bytes = [1, 2, 3];
    fixed (byte* pointerToFirst = bytes)
    {
        Console.WriteLine($"The address of the first array element: {(long)pointerToFirst:X}.");
        Console.WriteLine($"The value of the first array element: {*pointerToFirst}.");
    }
}
// Output is similar to:
// The address of the first array element: 2173F80B5C8.
// The value of the first array element: 1.

備註

您只能在fixed的內容中使用 語句。 包含不安全區塊的程式代碼必須使用 AllowUnsafeBlocks 編譯程式選項進行編譯。

您可以初始化宣告的指標,如下所示:

  • 使用陣列,如本文開頭的範例所示。 初始化的指標包含第一個數位專案的位址。

  • 使用變數的位址。 使用位址運算符&,如下列範例所示:

    unsafe
    {
        int[] numbers = [10, 20, 30];
        fixed (int* toFirst = &numbers[0], toLast = &numbers[^1])
        {
            Console.WriteLine(toLast - toFirst);  // output: 2
        }
    }
    

    物件欄位是可釘選的可移動變數的另一個範例。

    當初始化的指標包含物件字段或數位專案的位址時, fixed 語句會保證垃圾收集行程不會在語句主體執行期間重新放置或處置包含的物件實例。

  • 使用實作名為 GetPinnableReference之方法之型別的實例。 該方法必須傳回 refUnmanaged 類型的變數。 .NET 類型 System.Span<T> ,並 System.ReadOnlySpan<T> 使用此模式。 您可以釘選跨實例,如下列範例所示:

    unsafe
    {
        int[] numbers = [10, 20, 30, 40, 50];
        Span<int> interior = numbers.AsSpan()[1..^1];
        fixed (int* p = interior)
        {
            for (int i = 0; i < interior.Length; i++)
            {
                Console.Write(p[i]);  
            }
            // output: 203040
        }
    }
    

    如需詳細資訊,請參閱 Span<T>.GetPinnableReference() API 參考。

  • 使用字串,如下列範例所示:

    unsafe
    {
        var message = "Hello!";
        fixed (char* p = message)
        {
            Console.WriteLine(*p);  // output: H
        }
    }
    
  • 使用 固定大小的緩衝區

您可以在堆疊上配置記憶體,其中不受垃圾收集影響,因此不需要釘選。 若要這樣做,請使用 stackalloc 表達式

您也可以使用 fixed 關鍵詞來宣告 固定大小的緩衝區

C# 語言規格

如需詳細資訊,請參閱 C# 語言規格的下列幾節:

另請參閱