Bildirim deyimleri
Bildirim deyimi yeni bir değişken bildirir ve isteğe bağlı olarak bunu başlatır. Tüm değişkenler bildirilen türe sahiptir. .NET tür sistemindeki makalede türler hakkında daha fazla bilgi edinebilirsiniz. Genellikle bir bildirim bir tür ve değişken adı içerir. Ayrıca bir başlatma da içerebilir: =
işleç ve ardından bir ifade. Türü ile var
değiştirilebilir. Bildirim veya ifade, yeni değişkenin ref
mevcut bir depolama konumuna başvurduğunu bildirmek için değiştiriciyi içerebilir.
Örtülü olarak belirtilmiş yerel değişkenler
Yöntem kapsamında bildirilen değişkenlerin örtük bir "türü" var
olabilir. Örtük olarak yazılan bir yerel değişken, türü kendiniz bildirmişsiniz gibi kesin olarak yazılmıştır, ancak türü derleyici belirler. ve'nin a
b
aşağıdaki iki bildirimi işlevsel olarak eşdeğerdir:
var a = 10; // Implicitly typed.
int b = 10; // Explicitly typed.
Önemli
var
Null atanabilir başvuru türleri etkinken kullanıldığında, ifade türü null atanabilir olmasa bile her zaman null atanabilir bir başvuru türü anlamına gelir. Derleyicinin null durum analizi, olası null
bir değerin başvurulmalarına karşı koruma sağlar. Değişken hiçbir zaman null olabilecek bir ifadeye atanmazsa, derleyici herhangi bir uyarı yaymaz. Değişkeni null olabilecek bir ifadeye atarsanız, uyarılardan kaçınmak için başvuruyu kaldırmadan önce değişkenin null olmadığını test etmeniz gerekir.
Anahtar sözcüğün var
ortak kullanımı oluşturucu çağırma ifadeleridir. kullanımı var
, aşağıdaki örnekte gösterildiği gibi bir değişken bildiriminde ve nesne örneklemesinde tür adını yinelememenizi sağlar:
var xs = new List<int>();
C# 9.0 sürümünden başlayarak, alternatif olarak hedef türündeki new
ifadeyi kullanabilirsiniz:
List<int> xs = new();
List<int>? ys = new();
Desen eşleştirmede var
anahtar sözcüğü bir var
desende kullanılır.
Aşağıdaki örnekte iki sorgu ifadesi gösterilmektedir. İlk ifadede, kullanımına var
izin verilir, ancak gerekli değildir çünkü sorgu sonucunun türü açıkça olarak belirtilebilir IEnumerable<string>
. Ancak, ikinci ifadede sonucun var
anonim türlerden oluşan bir koleksiyon olmasına izin verir ve bu türün adı derleyicinin kendisi dışında erişilebilir değildir. kullanımı var
, sonuç için yeni bir sınıf oluşturma gereksinimini ortadan kaldırır. Örnek 2'de yineleme değişkeni item
de foreach
örtük olarak yazılmalıdır.
// Example #1: var is optional when
// the select clause specifies a string
string[] words = { "apple", "strawberry", "grape", "peach", "banana" };
var wordQuery = from word in words
where word[0] == 'g'
select word;
// Because each element in the sequence is a string,
// not an anonymous type, var is optional here also.
foreach (string s in wordQuery)
{
Console.WriteLine(s);
}
// Example #2: var is required because
// the select clause specifies an anonymous type
var custQuery = from cust in customers
where cust.City == "Phoenix"
select new { cust.Name, cust.Phone };
// var must be used because each item
// in the sequence is an anonymous type
foreach (var item in custQuery)
{
Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone);
}
Başvuru yerel öğeleri
Yerel bir değişkeni bildirmek ref
için değişkenin türünden önce anahtar sözcüğünü eklersinizref
. ref
Yerel, diğer depolama alanına başvuran bir değişkendir. yönteminin bir başv dönüş olarak bildirildiğinden GetContactInformation
emin olmak:
public ref Person GetContactInformation(string fname, string lname)
Şimdi şu iki atamanın karşıtlığını yapalım:
Person p = contacts.GetContactInformation("Brandie", "Best");
ref Person p2 = ref contacts.GetContactInformation("Brandie", "Best");
değişkenip
, değerinden GetContactInformation
döndürülen değerin bir kopyasını tutar. Bu, 'den döndürülenden ref
GetContactInformation
ayrı bir depolama konumudur. herhangi bir özelliğini p
değiştirirseniz, öğesinin Person
bir kopyasını değiştirirsiniz.
değişkenip2
, 'den GetContactInformation
dönüş için depolama konumuna ref
başvurur. bu, 'den GetContactInformation
döndürülen depolama alanıyla ref
aynıdır. herhangi bir özelliğini p2
değiştirirseniz, bir öğesinin tek örneğini Person
değiştirirsiniz.
Bir değere başvuruyla aynı şekilde erişebilirsiniz. Bazı durumlarda, bir değere başvuruyla erişmek, pahalı olabilecek kopyalama işleminden kaçınarak performansı artırır. Örneğin, aşağıdaki deyim bir değere başvurmak için kullanılan bir başvuru yerel değerinin nasıl tanımlandığını gösterir.
ref VeryLargeStruct reflocal = ref veryLargeStruct;
ref
anahtar sözcüğü hem yerel değişken bildiriminden önce hem de ikinci örnekteki değerden önce kullanılır. Değişken bildirimine her iki anahtar sözcüğün de ref
dahil edilmemesi ve her iki örnekte de atamanın başarısız olması, CS8172 derleyici hatasıyla sonuçlanır: "Bir değerle başvuruya göre değişken başlatılamıyor."
ref VeryLargeStruct reflocal = ref veryLargeStruct; // initialization
refLocal = ref anotherVeryLargeStruct; // reassigned, refLocal refers to different storage.
Başvuru yerel değişkenleri bildirildiğinde de başlatılmalıdır.
Aşağıdaki örnek, bir NumberStore
tamsayı değerleri dizisini depolayan bir sınıfı tanımlar. yöntemi, FindNumber
bağımsız değişken olarak geçirilen sayıdan büyük veya buna eşit olan ilk sayıyı başvuruyla döndürür. Bağımsız değişkenden büyük veya buna eşit bir sayı yoksa, yöntem 0 dizinindeki sayıyı döndürür.
using System;
class NumberStore
{
int[] numbers = { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 };
public ref int FindNumber(int target)
{
for (int ctr = 0; ctr < numbers.Length; ctr++)
{
if (numbers[ctr] >= target)
return ref numbers[ctr];
}
return ref numbers[0];
}
public override string ToString() => string.Join(" ", numbers);
}
Aşağıdaki örnek, 16'dan büyük veya 16'ya eşit olan ilk değeri almak için yöntemini çağırır NumberStore.FindNumber
. Çağıran daha sonra yöntemi tarafından döndürülen değeri ikiye katlar. Örnekten elde edilen çıkış, örneğin dizi öğelerinin NumberStore
değerine yansıtılan değişikliği gösterir.
var store = new NumberStore();
Console.WriteLine($"Original sequence: {store.ToString()}");
int number = 16;
ref var value = ref store.FindNumber(number);
value *= 2;
Console.WriteLine($"New sequence: {store.ToString()}");
// The example displays the following output:
// Original sequence: 1 3 7 15 31 63 127 255 511 1023
// New sequence: 1 3 7 15 62 63 127 255 511 1023
Başvuru dönüş değerleri desteği olmadan, dizi öğesinin dizini ve değeri döndürülerek böyle bir işlem gerçekleştirilir. Çağıran daha sonra bu dizini kullanarak değeri ayrı bir yöntem çağrısında değiştirebilir. Ancak, çağıran da erişmek ve muhtemelen diğer dizi değerleri değiştirmek için dizini değiştirebilirsiniz.
Aşağıdaki örnek, ref yerel yeniden atamasını FindNumber
kullanmak için yönteminin nasıl yeniden yazılabileceğini gösterir:
using System;
class NumberStore
{
int[] numbers = { 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023 };
public ref int FindNumber(int target)
{
ref int returnVal = ref numbers[0];
var ctr = numbers.Length - 1;
while ((ctr >= 0) && (numbers[ctr] >= target))
{
returnVal = ref numbers[ctr];
ctr--;
}
return ref returnVal;
}
public override string ToString() => string.Join(" ", numbers);
}
Bu ikinci sürüm, aranan sayının dizinin sonuna daha yakın olduğu senaryolarda daha uzun dizilerle daha verimlidir, dizi uçtan başa doğru yinelenir ve daha az öğenin incelenmesine neden olur.
Derleyici, değişkenler üzerinde ref
kapsam kurallarını zorunlu kılar: ref
yerel değerler, ref
parametreler ve ref
türlerdeki ref struct
alanlar. Kurallar, başvurunun başvurduğu nesneden uzun yaşamamasını sağlar. Yöntem parametreleriyle ilgili makalenin kapsam kuralları bölümüne bakın.
başvuru ve salt okunur
Değiştirici readonly
yerel değişkenlere ve ref
alanlara ref
uygulanabilir. Değiştirici readonly
, ifadeyi sağındaki etkiler. Aşağıdaki örnek bildirimlere bakın:
ref readonly int aConstant; // aConstant can't be value-reassigned.
readonly ref int Storage; // Storage can't be ref-reassigned.
readonly ref readonly int CantChange; // CantChange can't be value-reassigned or ref-reassigned.
- değer yeniden ataması , değişkenin değerinin yeniden atandığı anlamına gelir.
- başvuru ataması , değişkenin artık farklı bir nesneye başvurduğu anlamına gelir.
readonly ref
ve readonly ref readonly
bildirimleri yalnızca ref
içindeki ref struct
alanlarda geçerlidir.
kapsamlı başvuru
Bağlamsal anahtar sözcük scoped
, bir değerin ömrünü kısıtlar. Değiştirici, scoped
sırasıyla ref-safe-to-escape veya safe-to-escape ömrünü geçerli yöntemle kısıtlar. Etkili bir şekilde, değiştiriciyi scoped
eklemek kodunuzun değişkenin ömrünü uzatmayacağını onaylar.
Bir parametreye veya yerel değişkene uygulayabilirsiniz scoped
. Değiştirici scoped
, türü bir ref struct
olduğunda parametrelere ve yerel ayarlara uygulanabilir. Aksi takdirde, scoped
değiştirici yalnızca başv türü olan yerel değişkenlere uygulanabilir. Bu, değiştirici ile ref
bildirilen yerel değişkenleri ve ile bildirilen in
ref
parametreleri veya out
değiştiricileri içerir.
Değiştiriciscoped
, türü ref struct
bir struct
olduğunda , out
parametreleri ve ref
parametrelerinde bildirilen yöntemlere örtük olarak eklenirthis
.