Üye erişim işleçleri ve ifadeleri - nokta, dizin oluşturucu ve çağırma işleçleri.

Bir tür üyesine erişmek için birkaç işleç ve ifade kullanırsınız. Bu işleçler üye erişimini (.), dizi öğesini veya dizin oluşturucu erişimini ([]), uçtan dizine (^), aralığı (..), null koşullu işleçleri (?. ve ) ve ?[]yöntem çağırmayı (() içerir. Bunlar null koşullu üye erişimi ()?. ve dizin oluşturucu erişimi (?[]) işleçlerini içerir.

Üye erişim ifadesi .

Aşağıdaki örneklerde gösterildiği gibi, bir ad alanının veya türün üyesine erişmek için belirteci kullanırsınız . :

  • Aşağıdaki yönerge örneğindeusinggösterildiği gibi, bir ad alanı içinde iç içe bir ad alanına erişmek için kullanın.:
using System.Collections.Generic;
  • Aşağıdaki kodda gösterildiği gibi, ad alanı içindeki bir türe erişmek üzere nitelenmiş bir ad oluşturmak için kullanın.:
System.Collections.Generic.IEnumerable<int> numbers = [1, 2, 3];

Nitelenmiş adların kullanımını isteğe bağlı hale getirmek için bir using yönerge kullanın.

  • Aşağıdaki kodda gösterildiği gibi statik ve statik olmayan tür üyelerine erişmek için kullanın.:
List<double> constants =
[
    Math.PI,
    Math.E
];
Console.WriteLine($"{constants.Count} values to show:");
Console.WriteLine(string.Join(", ", constants));
// Output:
// 2 values to show:
// 3.14159265358979, 2.71828182845905

Bir uzantı yöntemine erişmek için de kullanabilirsiniz..

Dizin oluşturucu işleci []

Köşeli ayraçlar , []genellikle dizi, dizin oluşturucu veya işaretçi öğesi erişimi için kullanılır.

Dizi erişimi

Aşağıdaki örnekte dizi öğelerine nasıl erişirsiniz gösterilmektedir:

int[] fib = new int[10];
fib[0] = fib[1] = 1;
for (int i = 2; i < fib.Length; i++)
{
    fib[i] = fib[i - 1] + fib[i - 2];
}
Console.WriteLine(fib[fib.Length - 1]);  // output: 55

double[,] matrix = new double[2,2];
matrix[0,0] = 1.0;
matrix[0,1] = 2.0;
matrix[1,0] = matrix[1,1] = 3.0;
var determinant = matrix[0,0] * matrix[1,1] - matrix[1,0] * matrix[0,1];
Console.WriteLine(determinant);  // output: -3

Dizi dizini, bir dizinin karşılık gelen boyutunun sınırlarının dışındaysa, bir IndexOutOfRangeException oluşturulur.

Yukarıdaki örnekte gösterildiği gibi, bir dizi türü bildirirken veya bir dizi örneğini oluştururken köşeli ayraçlar da kullanırsınız.

Diziler hakkında daha fazla bilgi için bkz . Diziler.

Dizin oluşturucu erişimi

Aşağıdaki örnek dizin oluşturucu erişimini göstermek için .NET Dictionary<TKey,TValue> türünü kullanır:

var dict = new Dictionary<string, double>();
dict["one"] = 1;
dict["pi"] = Math.PI;
Console.WriteLine(dict["one"] + dict["pi"]);  // output: 4.14159265358979

Dizin oluşturucular, kullanıcı tanımlı bir türün örneklerini dizi dizinleme gibi dizinlemenize olanak tanır. Tamsayı olması gereken dizi dizinlerinden farklı olarak, dizin oluşturucu parametreleri herhangi bir türde olarak bildirilebilir.

Dizin oluşturucular hakkında daha fazla bilgi için bkz . Dizin oluşturucular.

[] öğesinin diğer kullanımları

İşaretçi öğesi erişimi hakkında bilgi için İşaretçiyle ilgili işleçler makalesinin İşaretçi öğesi erişim işleci [] bölümüne bakın.

Öznitelikleri belirtmek için köşeli ayraçlar da kullanırsınız:

[System.Diagnostics.Conditional("DEBUG")]
void TraceMethod() {}

Null koşullu işleçler ?. ve ?[]

Null koşullu işleç, bir üye erişimi (?.) veya öğe erişimi (?[]) işlemini yalnızca işlenen null olmayan olarak değerlendirilirse, işlecine uygular; aksi takdirde döndürür null. Bunun anlamı:

  • olarak değerlendirilirse anullveya a?[x] sonucunu a?.x elde edernull.

  • Null olmayan olarak değerlendirilirsea, veya a?[x] sonucu a?.x sırasıyla veya a[x]sonucuyla a.x aynıdır.

    Not

    Veya a[x] bir özel durum a?.x oluşturursa a.x veya a?[x] null aolmayan için aynı özel durumu oluşturursa. Örneğin, null olmayan bir dizi örneğiyse a ve x sınırlarının a?[x]adışındaysa bir IndexOutOfRangeExceptionoluşturur.

Null koşullu işleçler kısa devredir. Başka bir ifadeyle, koşullu üye veya öğe erişim işlemleri zincirindeki bir işlem döndürürse null, zincirin geri kalanı yürütülemez. Aşağıdaki örnekte, B olarak değerlendirilirse Anull değerlendirilmez ve C veya olarak değerlendirilirse AB değerlendirilmez null:

A?.B?.Do(C);
A?.B?[C];

Null A olabilir ancak BC A null değilse null olmazsa, yalnızca null koşullu işlecini uygulaması Agerekir:

A?.B.C();

Yukarıdaki örnekte, B değerlendirilmez ve C() null ise A çağrılmaz. Ancak zincirli üye erişimi kesintiye uğrarsa, örneğin içinde olduğu gibi (A?.B).C()parantezler kullanılırsa kısa devre gerçekleşmez.

Aşağıdaki örneklerde ve ?[] işleçlerinin kullanımı gösterilmektedir?.:

double SumNumbers(List<double[]> setsOfNumbers, int indexOfSetToSum)
{
    return setsOfNumbers?[indexOfSetToSum]?.Sum() ?? double.NaN;
}

var sum1 = SumNumbers(null, 0);
Console.WriteLine(sum1);  // output: NaN

List<double[]?> numberSets =
[
    [1.0, 2.0, 3.0],
    null
];

var sum2 = SumNumbers(numberSets, 0);
Console.WriteLine(sum2);  // output: 6

var sum3 = SumNumbers(numberSets, 1);
Console.WriteLine(sum3);  // output: NaN
namespace MemberAccessOperators2;

public static class NullConditionalShortCircuiting
{
    public static void Main()
    {
        Person? person = null;
        person?.Name.Write(); // no output: Write() is not called due to short-circuit.
        try
        {
            (person?.Name).Write();
        }
        catch (NullReferenceException)
        {
            Console.WriteLine("NullReferenceException");
        }; // output: NullReferenceException
    }
}

public class Person
{
    public required FullName Name { get; set; }
}

public class FullName
{
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
    public void Write() => Console.WriteLine($"{FirstName} {LastName}");
}

Yukarıdaki iki örnekten ilki null koşullu işlemin nullsonucunun olması durumunda değerlendirilecek alternatif bir ifade belirtmek için null birleşim işlecini ?? de kullanır.

veya null atanamaz bir değer türündeyse a.xTa?.x veya a?[x] karşılık gelen null atanabilir değer türündeyse.T?a[x] türünde Tbir ifadeye ihtiyacınız varsa, aşağıdaki örnekte gösterildiği gibi null-birleşim işlecini ?? null-koşullu ifadeye uygulayın:

int GetSumOfFirstTwoOrDefault(int[]? numbers)
{
    if ((numbers?.Length ?? 0) < 2)
    {
        return 0;
    }
    return numbers[0] + numbers[1];
}

Console.WriteLine(GetSumOfFirstTwoOrDefault(null));  // output: 0
Console.WriteLine(GetSumOfFirstTwoOrDefault([]));  // output: 0
Console.WriteLine(GetSumOfFirstTwoOrDefault([3, 4, 5]));  // output: 7

Yukarıdaki örnekte işlecini ?? kullanmıyorsanız, numbers?.Length < 2 değerinin ne zaman numbers olduğunu nulldeğerlendirirfalse.

Not

İşleç ?. , soldaki işlenenini en fazla bir kez değerlendirir ve null olmayan olarak doğrulandıktan sonra olarak değiştirilemeyeceğini null garanti eder.

Null koşullu üye erişim işleci ?. , Elvis işleci olarak da bilinir.

İş parçacığı güvenli temsilci çağırma

Aşağıdaki kodda gösterildiği gibi, bir temsilcinin ?. null olup olmadığını denetlemek ve iş parçacığı açısından güvenli bir şekilde (örneğin, bir olay oluştururken) çağırmak için işlecini kullanın:

PropertyChanged?.Invoke(…)

Bu kod aşağıdaki koda eşdeğerdir:

var handler = this.PropertyChanged;
if (handler != null)
{
    handler(…);
}

Yukarıdaki örnek, yalnızca null handler olmayan bir çağrılmasını sağlamanın iş parçacığı açısından güvenli bir yoludur. Temsilci örnekleri sabit olduğundan, hiçbir iş parçacığı yerel değişken tarafından handler başvuruda bulunan nesneyi değiştiremez. Özellikle, başka bir iş parçacığı tarafından yürütülen kod olay aboneliğini PropertyChanged kaldırır ve PropertyChanged önceye handler dönüşürsenull, tarafından handler başvurulan nesne etkilenmez.

Çağırma ifadesi ()

Bir yöntemi çağırmak veya temsilci çağırmak için parantezleri ()kullanın.

Aşağıdaki örnek, bağımsız değişkenlerle veya bağımsız değişkenler olmadan bir yöntemi çağırmayı ve temsilci çağırmayı gösterir:

Action<int> display = s => Console.WriteLine(s);

List<int> numbers =
[
    10,
    17
];
display(numbers.Count);   // output: 2

numbers.Clear();
display(numbers.Count);   // output: 0

Ayrıca işleciyle new bir oluşturucu çağırırken parantezler de kullanırsınız.

() diğer kullanımları

İfadedeki işlemlerin değerlendirilme sırasını ayarlamak için ayraç da kullanırsınız. Daha fazla bilgi için bkz . C# işleçleri.

Açık tür dönüştürmeleri gerçekleştiren atama ifadeleri de ayraç kullanır.

^ bitiş işlecinden dizin

Dizin ve aralık işleçleri, sayılabilir bir türle kullanılabilir. Sayılabilir tür, erişilebilir get erişimciye sahip veya Length adlı Count bir int özelliğe sahip olan bir türdür. Koleksiyon ifadeleri de sayılabilir türlere dayanır.

^ işleci, bir dizinin sonundan öğe konumunu gösterir. Bir uzunluk lengthdizisi için, ^n bir dizinin başından uzaklığı length - n olan öğeyi gösterir. Örneğin, ^1 bir dizinin son öğesini ve ^length bir dizinin ilk öğesini gösterir.

int[] xs = [0, 10, 20, 30, 40];
int last = xs[^1];
Console.WriteLine(last);  // output: 40

List<string> lines = ["one", "two", "three", "four"];
string prelast = lines[^2];
Console.WriteLine(prelast);  // output: three

string word = "Twenty";
Index toFirst = ^word.Length;
char first = word[toFirst];
Console.WriteLine(first);  // output: T

Yukarıdaki örnekte gösterildiği gibi ifade ^e türündedir System.Index . ifadesinde ^e, sonucunun e örtük olarak olarak olarak intdönüştürülebilir olması gerekir.

Ayrıca, bir dizi dizin oluşturmak için işlecini aralık işleciyle birlikte de kullanabilirsiniz^. Daha fazla bilgi için bkz . Dizinler ve aralıklar.

C# 13'ten başlayarak, bitiş işlecinden dizin bir nesne başlatıcıda kullanılabilir.

Aralık işleci ..

.. işleci, işlenenleri olarak bir dizin aralığının başlangıcını ve sonunu belirtir. Sol işlenen, bir aralığın kapsayıcı bir başlangıcıdır. Sağ işlenen, aralığın özel bir ucudur. aşağıdaki örnekte gösterildiği gibi işlenenlerden biri, bir dizinin başından veya sonundan bir dizin olabilir:

int[] numbers = [0, 10, 20, 30, 40, 50];
int start = 1;
int amountToTake = 3;
int[] subset = numbers[start..(start + amountToTake)];
Display(subset);  // output: 10 20 30

int margin = 1;
int[] inner = numbers[margin..^margin];
Display(inner);  // output: 10 20 30 40

string line = "one two three";
int amountToTakeFromEnd = 5;
Range endIndices = ^amountToTakeFromEnd..^0;
string end = line[endIndices];
Console.WriteLine(end);  // output: three

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

Yukarıdaki örnekte gösterildiği gibi ifade a..b türündedir System.Range . ifadesindea..b, ve b sonuçlarının a veya Indexöğesine örtük olarak dönüştürülebilir Int32 olması gerekir.

Önemli

değeri negatif olduğunda'dan intIndex oluşturmaya ArgumentOutOfRangeException yönelik örtük dönüştürmeler.

Açık uçlu bir aralık elde etmek için işlecin işlenenlerinden .. herhangi birini atlayabilirsiniz:

  • a.. eşdeğerdir a..^0
  • ..b eşdeğerdir 0..b
  • .. eşdeğerdir 0..^0
int[] numbers = [0, 10, 20, 30, 40, 50];
int amountToDrop = numbers.Length / 2;

int[] rightHalf = numbers[amountToDrop..];
Display(rightHalf);  // output: 30 40 50

int[] leftHalf = numbers[..^amountToDrop];
Display(leftHalf);  // output: 0 10 20

int[] all = numbers[..];
Display(all);  // output: 0 10 20 30 40 50

void Display<T>(IEnumerable<T> xs) => Console.WriteLine(string.Join(" ", xs));

Aşağıdaki tabloda koleksiyon aralıklarını ifade etmenin çeşitli yolları gösterilmektedir:

Aralık işleci ifadesi Açıklama
.. Koleksiyondaki tüm değerler.
..end Başlangıçtan özel olarak değerlere end .
start.. Dahil olandan start sonuna kadar olan değerler.
start..end Dahil olandan start yalnızca öğesine kadar olan end değerler.
^start.. Dahil olandan start sona kadar olan değerler, sonundan sonuna kadar sayma.
..^end Baştan sona kadar olan end değerler yalnızca sonundan sayma.
start..^end Dahil değerlerden startend yalnızca sonundan saymaya kadar olan değerler.
^start..^end Dahil değerlerden startend yalnızca her ikisine de sonundan sayma değerleri.

Aşağıdaki örnek, önceki tabloda sunulan tüm aralıkları kullanmanın etkisini gösterir:

int[] oneThroughTen =
[
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10
];

Write(oneThroughTen, ..);
Write(oneThroughTen, ..3);
Write(oneThroughTen, 2..);
Write(oneThroughTen, 3..5);
Write(oneThroughTen, ^2..);
Write(oneThroughTen, ..^3);
Write(oneThroughTen, 3..^4);
Write(oneThroughTen, ^4..^2);

static void Write(int[] values, Range range) =>
    Console.WriteLine($"{range}:\t{string.Join(", ", values[range])}");
// Sample output:
//      0..^0:      1, 2, 3, 4, 5, 6, 7, 8, 9, 10
//      0..3:       1, 2, 3
//      2..^0:      3, 4, 5, 6, 7, 8, 9, 10
//      3..5:       4, 5
//      ^2..^0:     9, 10
//      0..^3:      1, 2, 3, 4, 5, 6, 7
//      3..^4:      4, 5, 6
//      ^4..^2:     7, 8

Daha fazla bilgi için bkz . Dizinler ve aralıklar.

Belirteç.., koleksiyon ifadesinde spread işleci olarak da kullanılır.

İşleç aşırı yüklenebilirliği

., (), ^ve .. işleçleri aşırı yüklenemez. işleci [] de aşırı yüklenemez bir işleç olarak kabul edilir. Kullanıcı tanımlı türlerle dizin oluşturmayı desteklemek için dizin oluşturucuları kullanın.

C# dili belirtimi

Daha fazla bilgi için C# dil belirtiminin aşağıdaki bölümlerine bakın:

Dizinler ve aralıklar hakkında daha fazla bilgi için özellik teklifi notu'na bakın.

Ayrıca bkz.