fixed Deyimi (C# Başvurusu)fixed Statement (C# Reference)

fixed İfade, çöp toplayıcısının taşınabilir bir değişkenin yerini değiştirmesini engeller.The fixed statement prevents the garbage collector from relocating a movable variable. Deyime yalnızca güvenli olmayan bir bağlamda izin verilir. emniyetsiz fixedThe fixed statement is only permitted in an unsafe context. Sabit boyutlu arabellekleroluşturmak için fixed anahtar sözcüğünü de kullanabilirsiniz.You can also use the fixed keyword to create fixed size buffers.

fixed İfade, yönetilen bir değişkene bir işaretçi ayarlar ve deyimin yürütülmesi sırasında bu değişkene "PIN" koyar.The fixed statement sets a pointer to a managed variable and "pins" that variable during the execution of the statement. Taşınabilir olarak yönetilen değişkenlere yönelik işaretçiler yalnızca bir fixed bağlamda yararlıdır.Pointers to movable managed variables are useful only in a fixed context. fixed Bağlam olmadan çöp toplama, değişkenleri tahmin edilmemiş şekilde yeniden konumlandırmaya yönelik olabilir.Without a fixed context, garbage collection could relocate the variables unpredictably. C# Derleyici yalnızca bir fixed ifadede yönetilen değişkene bir işaretçi atamanızı sağlar.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;
    }
}

Bir diziyi, dizeyi, sabit boyutlu arabelleği veya bir değişkenin adresini kullanarak bir işaretçiyi başlatabilirsiniz.You can initialize a pointer by using an array, a string, a fixed-size buffer, or the address of a variable. Aşağıdaki örnek, değişken adreslerinin, dizilerin ve dizelerin kullanımını göstermektedir: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]) { /*...*/ } 

7,3 ile C# başlayarak, fixed ifade diziler, dizeler, sabit boyutlu arabellekler veya yönetilmeyen değişkenlerin ötesinde ek türler üzerinde çalışır.Starting with C# 7.3, the fixed statement operates on additional types beyond arrays, strings, fixed size buffers, or unmanaged variables. Adlı GetPinnableReference bir yöntemi uygulayan herhangi bir tür sabitlenebilir.Any type that implements a method named GetPinnableReference can be pinned. , GetPinnableReference Yönetilmeyen türdebir ref değişken döndürmelidir.The GetPinnableReference must return a ref variable of an unmanaged type. .NET Core 2,0 System.Span<T> ' System.ReadOnlySpan<T> de sunulan .net türleri bu düzenin kullanımını ve sabitlenebilir.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. Bu, aşağıdaki örnekte gösterilmiştir: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);
    }
}

Bu modele katılması gereken türler oluşturuyorsanız, bu düzenin uygulanması örneği için bkz Span<T>.GetPinnableReference() .If you are creating types that should participate in this pattern, see Span<T>.GetPinnableReference() for an example of implementing the pattern.

Aynı türde olan birden çok işaretçi tek bir bildirimde başlatılabilir:Multiple pointers can be initialized in one statement if they are all the same type:

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

Farklı türlerin işaretçilerini başlatmak için aşağıdaki örnekte gösterildiği gibi fixed deyimlerini iç içe geçirebilirsiniz.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.
    }
}

Deyimdeki kod yürütüldükten sonra, sabitlenmiş değişkenler sabitlenir ve çöp toplamaya tabidir.After the code in the statement is executed, any pinned variables are unpinned and subject to garbage collection. Bu nedenle, bu değişkenleri fixed deyimin dışında işaret etmez.Therefore, do not point to those variables outside the fixed statement. fixed Bildiriminde belirtilen değişkenler, bu ifadeye göre kapsamlandırılır ve daha kolay hale getirir: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.

fixed Deyimlerde başlatılan işaretçiler salt okunur değişkenlerdir.Pointers initialized in fixed statements are readonly variables. İşaretçi değerini değiştirmek istiyorsanız, ikinci bir işaretçi değişkeni bildirmeniz ve bunu değiştirmeniz gerekir.If you want to modify the pointer value, you must declare a second pointer variable, and modify that. fixed İfadede belirtilen değişken değiştirilemez: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.
}

Yığın üzerinde bellek ayırabilirsiniz, burada çöp toplamaya tabi değildir ve bu nedenle sabitlenmiş olması gerekmez.You can allocate memory on the stack, where it is not subject to garbage collection and therefore does not need to be pinned. Bunu yapmak için stackalloc işlecinikullanın.To do that use the stackalloc operator.

C# dili belirtimiC# language specification

Daha fazla bilgi için, C# dil belirtiminin fixed deyimin bölümüne bakın.For more information, see The fixed statement section of the C# language specification.

Ayrıca bkz.See also