Üye erişim işleçleri ve ifadeleri (C# Başvurusu)

Bir tür üyesine eriştiğinizde aşağıdaki işleçleri ve ifadeleri kullanabilirsiniz:

Üye erişim ifadesi.

.Aşağıdaki örneklerde gösterildiği gibi, belirteci, bir ad uzayı veya bir tür üyesine erişmek için kullanabilirsiniz:

  • .Aşağıdaki bir using yönerge örneğinde gösterildiği gibi, bir ad alanı içinde iç içe geçmiş bir ad alanına erişmek için kullanın:
using System.Collections.Generic;
  • .Aşağıdaki kodun gösterdiği gibi, bir 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 = new int[] { 1, 2, 3 };

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

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

Ayrıca, . bir genişletme yöntemineerişmek için kullanabilirsiniz.

Indexer işleci []

Köşeli parantezler, [] genellikle Array, Indexer veya pointer öğesi erişimi için kullanılır.

Dizi erişimi

Aşağıdaki örnek, dizi öğelerine nasıl erişileceğini göstermektedir:

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

Bir dizi dizini, bir dizi karşılık gelen boyutun sınırları dışındaysa, bir oluşturulur IndexOutOfRangeException .

Yukarıdaki örnekte gösterildiği gibi, bir dizi türü bildirdiğinizde veya bir dizi örneği örneklediğinizde köşeli parantezleri de kullanabilirsiniz.

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

Dizin Oluşturucu erişimi

Aşağıdaki örnek, Dictionary<TKey,TValue> Dizin Oluşturucu erişimini göstermek için .NET 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 örneklerinin, dizi dizini oluşturma gibi benzer şekilde dizinlemesini sağlar. Tamsayı olması gereken dizi dizinlerinin aksine, Dizin Oluşturucu parametreleri herhangi bir türde olacak şekilde bildirilmelidir.

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

[] Diğer kullanımları

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

Ayrıca, öznitelikleribelirtmek için köşeli parantezleri de kullanabilirsiniz:

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

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

C# 6 ve üzeri sürümlerde kullanılabilir, null koşullu bir operatör, ?. yalnızca o işlenen null olmayan olarak değerlendiriliyorsa işlenene bir üye erişimi, veya öğe erişimiuygular ?[] ; Aksi takdirde, döndürür null . Yani

  • aOlarak değerlendirilirse null , a?.x veya a?[x] olur null .

  • aNull olmayan olarak değerlendirilirse, veya sonucu, a?.x sırasıyla veya sonucu ile a?[x] aynıdır a.x a[x] .

    Not

    a.xYa da a[x] bir özel durum oluşturursa a?.x ya da a?[x] null olmayan bir özel durum oluşturur a . Örneğin, a null olmayan bir dizi örneğidir ve x sınırları dışındaysa a a?[x] bir oluşturur IndexOutOfRangeException .

Null koşullu işleçler kısa devre dışı. Diğer bir deyişle, bir koşullu üye veya öğe erişim işlemleri zincirindeki bir işlem dönerse null , zincir geri kalanı yürütülmez. Aşağıdaki örnekte, B A olarak değerlendirilirse null ve C değerlendirmesi durumunda hesaplanmaz A B null :

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

Null olabilir, ancak null değilse null A B C olamaz, yalnızca şu şekilde null koşullu işleç uygulamanız gerekir A :

A?.B.C();

Önceki örnekte, B değerlendirilmemiştir ve C() null ise çağrılmaz A . Ancak, zincirleme üye erişimi kesintiye uğrarsa (örneğin, içinde parantez ile), (A?.B).C() kısa devre gerçekleştirmeyen olmaz.

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

var numberSets = new List<double[]>
{
    new[] { 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
using System;
using System.Collections.Generic;
using System.Linq;

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 FullName Name { get; set; }
    }

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

Önceki iki örnekten ilki aynı zamanda null birleşim işlecini ?? kullanır, bu da null koşullu bir işlemin sonucu olarak değerlendirmek için alternatif bir ifade belirtir null .

a.xYa da a[x] null yapılamayan bir değer türü ise T a?.x veya a?[x] buna karşılık gelen null atanabilir değer türüdür T? . Türünde bir ifadeye ihtiyacınız varsa T , ?? 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(new int[0]));  // output: 0
Console.WriteLine(GetSumOfFirstTwoOrDefault(new[] { 3, 4, 5 }));  // output: 7

Önceki örnekte, işlecini kullanmıyorsanız, ?? numbers?.Length < 2 false ne zaman numbers olduğunu değerlendirir null .

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

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

?.Bir temsilcinin null olup olmadığını denetlemek ve iş parçacığı güvenli bir şekilde (örneğin, bir olayyükselttiğinizde) aşağıdaki kodun gösterdiği gibi, bir temsilciyi çağırmak için işlecini kullanın:

PropertyChanged?.Invoke(…)

Bu kod, C# 5 veya daha önceki bir sürümünde kullanacağınız aşağıdaki koda eşdeğerdir:

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

Bu, yalnızca null olmayan bir değer çağrılmasını sağlamak için iş parçacığı açısından güvenli bir yoldur handler . Temsilci örnekleri sabit olduğu için, hiçbir iş parçacığı yerel değişken tarafından başvurulan nesneyi değiştiremez handler . Özellikle, başka bir iş parçacığı tarafından yürütülen kod, olaydan aboneliği kaldırır PropertyChanged ve PropertyChanged null önce gelirse handler , tarafından başvurulan nesne handler etkilenmeden kalır. ?.İşleci sol taraftaki işlenenini birden çok kez değerlendirir ve null null olmayan olarak doğrulandıktan sonra olarak değiştirilemez.

Çağırma ifadesi ()

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

Aşağıdaki örnek, bağımsız değişkenler içeren veya olmayan bir yöntemin nasıl çağrılacağını gösterir ve bir temsilciyi çağırır:

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

var numbers = new List<int>();
numbers.Add(10);
numbers.Add(17);
display(numbers.Count);   // output: 2

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

İşleci ile bir Oluşturucu çağırdığınızda parantezleri de kullanabilirsiniz new .

() Diğer kullanımları

Ayrıca, bir ifadede işlemlerin değerlendirileceği sırayı ayarlamak için parantez de kullanabilirsiniz. Daha fazla bilgi için bkz. C# işleçleri.

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

Bitiş işlecinden Dizin ^

C# 8,0 ve üzeri sürümlerde kullanılabilen işleç, ^ öğe konumunun bir dizinin sonundan olduğunu gösterir. Bir uzunluk sırası için length , ^n length - n bir dizi başlangıcının sonuna kadar olan öğesine işaret eder. Örneğin, ^1 bir sıranın son öğesine işaret eder ve ^length dizinin ilk öğesine işaret eder.

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

var lines = new List<string> { "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, ifadesi ^e System.Index türüdür. İfadesinde ^e , sonucu e örtük olarak dönüştürülebilir olmalıdır int .

Ayrıca ^ bir dizin aralığı oluşturmak için işleci Aralık işleciyle de kullanabilirsiniz. Daha fazla bilgi için bkz. Dizinler ve aralıklar.

Aralık işleci..

C# 8,0 ve üzeri sürümlerde kullanılabilen işleç, .. işlenen bir dizin aralığının başlangıcını ve sonunu belirtir. Sol işlenen bir aralığın kapsamlı bir başlangıcı olur. Sağ işlenen bir aralığın dışlamalı bir sonu. Her iki işlenen de, aşağıdaki örnekte gösterildiği gibi, bir sıranın başından veya sonundan bir dizin olabilir:

int[] numbers = new[] { 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, ifadesi a..b System.Range türüdür. İfadesinde a..b , a ve sonuçları b örtülü olarak veya olarak dönüştürülebilir olmalıdır int Index .

..Açık uçlu bir Aralık almak 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 = new[] { 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));

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

Operatör overloadability

.,, () ^ , Ve .. işleçleri aşırı yüklenemez. []İşleci, aşırı yüklenebilir olmayan 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 belirtimininaşağıdaki bölümlerine bakın:

Dizinler ve aralıklar hakkında daha fazla bilgi için bkz. özellik teklifi Note.

Ayrıca bkz.