fixed Deyimi (C# Başvurusu)
fixedİfade, çöp toplayıcısının taşınabilir bir değişkenin yerini değiştirmesini engeller. fixedDeyime yalnızca güvenli olmayan bir bağlamda izin verilir. fixed Sabit boyutlu arabellekleroluşturmak için anahtar sözcüğünü de kullanabilirsiniz.
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. Taşınabilir olarak yönetilen değişkenlere yönelik işaretçiler yalnızca bir bağlamda yararlıdır fixed . Bağlam olmadan fixed çöp toplama, değişkenleri tahmin edilmemiş şekilde yeniden konumlandırmaya yönelik olabilir. C# derleyicisi yalnızca bir ifadede yönetilen değişkene bir işaretçi atamanızı sağlar fixed .
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. Aşağıdaki örnek, değişken adreslerinin, dizilerin ve dizelerin kullanımını göstermektedir:
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]) { /*...*/ }
C# 7,3 ' den başlayarak, fixed ifade diziler, dizeler, sabit boyutlu arabellekler veya yönetilmeyen değişkenlerin ötesinde ek türler üzerinde çalışır. Adlı bir yöntemi uygulayan herhangi bir tür GetPinnableReference sabitlenebilir. , GetPinnableReference ref Yönetilmeyen türdebir değişken döndürmelidir. .Net System.Span<T> System.ReadOnlySpan<T> Core 2,0 ' de sunulan .net türleri bu düzenin kullanımını ve sabitlenebilir. Bu, aşağıdaki örnekte gösterilmiştir:
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 Span<T>.GetPinnableReference() düzenin uygulanması örneği için bkz..
Aynı türde olan birden çok işaretçi tek bir bildirimde başlatılabilir:
fixed (byte* ps = srcarray, pd = dstarray) {...}
Farklı türlerin işaretçilerini başlatmak için fixed Aşağıdaki örnekte gösterildiği gibi deyimlerini iç içe geçirebilirsiniz.
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. Bu nedenle, bu değişkenleri deyimin dışında işaret etmez fixed . Bildiriminde belirtilen değişkenler, fixed Bu ifadeye göre kapsamlandırılır ve daha kolay hale getirir:
fixed (byte* ps = srcarray, pd = dstarray)
{
...
}
// ps and pd are no longer in scope here.
fixedDeyimlerde başlatılan işaretçiler salt okunur değişkenlerdir. İşaretçi değerini değiştirmek istiyorsanız, ikinci bir işaretçi değişkeni bildirmeniz ve bunu değiştirmeniz gerekir. İfadede belirtilen değişken fixed değiştirilemez:
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. Bunu yapmak için bir stackalloc ifadekullanın.
C# dili belirtimi
Daha fazla bilgi için C# dil belirtiminin fixed deyimin bölümüne bakın.