Bildirim deyimleri

Bildirim deyimi yeni bir değişken bildirir ve isteğe bağlı olarak bunu başlatır. Tüm değişkenlerin türü bildirildi. .NET tür sistemindeki makalede türler hakkında daha fazla bilgi edinebilirsiniz. Bir bildirim genellikle 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 vardeğ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şkenler örtük bir "türe" varsahip olabilir. Örtük olarak yazılan bir yerel değişken, türü kendiniz bildirmişsiniz gibi kesin bir şekilde türlendirilir, ancak derleyici türü belirler. ve'nin ab aşağıdaki iki bildirimi işlevsel olarak eşdeğerdir:

var a = 10; // Implicitly typed.
int b = 10; // Explicitly typed.

Önemli

varNull 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 çözümlemesi, olası null bir değerin başvurularını kaldırmaya 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 etmelisiniz.

Anahtar sözcüğün var yaygın kullanımlarından biri 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 bir 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 olarak IEnumerable<string>belirtilebilir. 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 foreach yineleme değişkeni item de ö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

Bir yerel bildirmek ref için ref değişkenin türünden önce anahtar sözcüğünü eklersiniz. ref Yerel, diğer depolama alanına başvuran bir değişkendir. yönteminin GetContactInformation bir başv dönüş olarak bildirildiğinden 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 GetContactInformationdöndürülen değerin bir kopyasını barındırıyor. Bu, 'den döndürülenden refGetContactInformationayrı bir depolama konumudur. herhangi bir özelliğini pdeğiştirirseniz, öğesinin bir kopyasını Persondeğiştirirsiniz.

değişkenip2, 'den GetContactInformationdönüş için depolama konumuna refbaşvurur. bu, 'den GetContactInformationgelen verim ile ref aynı depolama alanıdır. herhangi bir özelliğini p2değiştirirseniz, bir öğesinin tek örneğini Persondeğiştirirsiniz.

Bir değere başvuruyla aynı şekilde erişebilirsiniz. Bazı durumlarda, başvuru yoluyla bir değere erişmek, pahalı olabilecek bir 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şv yerel değerini nasıl tanımlayabileceğinizi gösterir.

ref VeryLargeStruct reflocal = ref veryLargeStruct;

anahtar ref sözcüğü hem yerel değişken bildiriminden önce hem de ikinci örnekteki değerden önce kullanılır. Her iki örnekte de değişken bildirimine ve atamasına her iki ref anahtar sözcüğün de dahil edilmemesi cs8172 derleyici hatasıyla sonuçlanır: "Bir değerle bir başvuru değişkeni 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 hala 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ıya başvurarak 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 çıktı, ö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ı kullanmak için yönteminin nasıl FindNumber 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 parametreleri makalesindeki 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.
  • value reassignment , 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 structalanlarda 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 structolduğ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 inref bildirilen parametreleri veya out değiştiricileri içerir.

Değiştiriciscoped, türü ref structbir structolduğunda , out parametreleri ve ref parametrelerinde bildirilen yöntemlere örtük olarak eklenirthis.

Ayrıca bkz.