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 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şkenlerin örtük bir "türü" varolabilir. Ö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 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 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 GetContactInformationdöndürülen değerin bir kopyasını tutar. Bu, 'den döndürülenden refGetContactInformationayrı bir depolama konumudur. herhangi bir özelliğini pdeğiştirirseniz, öğesinin Personbir kopyasını değiştirirsiniz.

değişkenip2, 'den GetContactInformationdönüş için depolama konumuna refbaşvurur. bu, 'den GetContactInformationdöndürülen depolama alanıyla ref aynı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, 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 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 bildirilen inref 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.