Operator dan ekspresi akses anggota - operator titik, pengindeks, dan pemanggilan.
Anda menggunakan beberapa operator dan ekspresi untuk mengakses anggota jenis. Operator ini termasuk akses anggota (.
), elemen array atau akses pengindeks ([]
), index-from-end (^
), range (..
), null-conditional operators (?.
dan ?[]
), dan method invocation (()
). Ini termasuk operator akses anggota null-conditional (?.
), dan akses pengindeks (?[]
).
.
(akses anggota): untuk mengakses anggota dari namespace layanan atau jenis[]
(elemen array atau akses pengindeks): untuk mengakses elemen array atau pengindeks jenis?.
dan?[]
(operator null-kondisional): untuk melakukan operasi akses anggota atau elemen hanya jika operand bukan null()
(pemanggilan): untuk memanggil metode akses atau memanggil delegasi^
(indeks dari akhir): untuk menunjukkan bahwa posisi elemen berasal dari akhir urutan..
(rentang): untuk menentukan rentang indeks yang dapat Anda gunakan untuk mendapatkan rentang elemen urutan
Ekspresi akses anggota .
Anda menggunakan token .
untuk mengakses anggota dari namespace layanan atau jenis, seperti yang ditunjukkan contoh berikut:
- Gunakan
.
untuk mengakses namespace layanan berlapis dalam sebuah namespace layanan, seperti yang ditunjukkan contohusing
direktif berikut:
using System.Collections.Generic;
- Gunakan
.
untuk membentuk nama yang memenuhi syarat untuk mengakses jenis dalam namespace layanan, seperti yang ditunjukkan oleh kode berikut:
System.Collections.Generic.IEnumerable<int> numbers = [1, 2, 3];
Gunakan using
direktif untuk memanfaatkan nama yang memenuhi syarat opsional.
- Gunakan
.
untuk mengakses anggota jenis, statis dan non-statis, seperti yang ditunjukkan oleh kode berikut:
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
Anda juga dapat menggunakan .
untuk mengakses metode ekstensi.
Operator pengindeks []
Kurung siku, []
, biasanya digunakan untuk mengakses elemen array, pengindeks, atau penunjuk.
Mengakses array
Contoh berikut menunjukkan cara mengakses elemen array:
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
Jika indeks array berada di luar batas dimensi array yang sesuai, maka IndexOutOfRangeException akan dilemparkan.
Seperti yang ditunjukkan contoh sebelumnya, Anda juga menggunakan kurung siku saat mendeklarasikan jenis array atau untuk instansiasi instans array.
Untuk informasi selengkapnya tentang array, lihat Array.
Mengakses pengindeks
Contoh berikut menggunakan jenis Dictionary<TKey,TValue> .NET untuk menunjukkan akses pengindeks:
var dict = new Dictionary<string, double>();
dict["one"] = 1;
dict["pi"] = Math.PI;
Console.WriteLine(dict["one"] + dict["pi"]); // output: 4.14159265358979
Pengindeks memungkinkan Anda mengindeks instans jenis yang ditentukan pengguna dengan cara yang sama seperti pengindeksan array. Tidak seperti indeks array, yang harus berupa bilangan bulat, parameter pengindeks dapat dideklarasikan berdasarkan jenis apa pun.
Untuk informasi selengkapnya tentang pengindeks, lihat Pengindeks.
Penggunaan lainnya dari []
Untuk informasi tentang akses elemen penunjuk, lihat bagian Operator akses elemen Penunjuk [] dari artikel Operator terkait Penunjuk.
Anda juga menggunakan kurung siku untuk menentukan atribut:
[System.Diagnostics.Conditional("DEBUG")]
void TraceMethod() {}
Operator ?.
null-conditional dan ?[]
Operator null-conditional menerapkan operasi akses anggota (?.
) atau akses elemen (?[]
) ke operand-nya hanya jika operand tersebut mengevaluasi ke non-null; jika tidak, itu mengembalikan null
. Yaitu:
Jika
a
mengevaluasi kenull
, hasil daria?.x
ataua?[x]
adalahnull
.Jika
a
mengevaluasi ke bukan null, hasil daria?.x
ataua?[x]
sama dengan hasil daria.x
ataua[x]
, berturut-turut.Catatan
Jika
a.x
ataua[x]
melempar pengecualian,a?.x
ataua?[x]
akan melemparkan pengecualian yang sama untuka
bukan null. Misalnya, jikaa
adalah instans array bukan null danx
berada di luar batasa
,a?[x]
akan melemparkan IndexOutOfRangeException.
Operator null-kondisional memiliki sirkuit pendek. Artinya, jika satu operasi dalam rantai anggota kondisional atau operasi akses elemen mengembalikan null
, sisa rantai tidak dijalankan. Dalam contoh berikut, B
tidak dievaluasi jika A
dievaluasi ke null
dan C
tidak dievaluasi jika A
atau B
mengevaluasi ke null
:
A?.B?.Do(C);
A?.B?[C];
Jika A
mungkin null tetapi B
dan C
tidak akan null jika A tidak null, Anda hanya perlu menerapkan operator null-conditional ke A
:
A?.B.C();
Dalam contoh sebelumnya, B
tidak dievaluasi dan C()
tidak dipanggil jika A
null. Namun, jika akses anggota berantai terganggu, misalnya oleh tanda kurung seperti dalam (A?.B).C()
, sirkuit pendek tidak terjadi.
Contoh berikut menunjukkan penggunaan operator ?.
dan ?[]
:
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}");
}
Contoh pertama dari dua contoh sebelumnya juga menggunakan operator penggabungan null??
untuk menentukan ekspresi alternatif untuk melakukan evaluasi jika hasil operasi null-kondisional adalah null
.
Jika a.x
atau a[x]
berjenis nilai yang tidak dapat diubah ke null T
, a?.x
atau a?[x]
merupakan jenis nilai yang dapat diubah ke nullT?
yang sesuai. Jika Anda memerlukan ekspresi jenis T
, terapkan operator penggabungan null ??
ke ekspresi null-kondisional, seperti yang ditunjukkan contoh berikut:
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
Dalam contoh sebelumnya, jika Anda tidak menggunakan operator ??
, numbers?.Length < 2
melakukan evaluasi ke false
saat numbers
adalah null
.
Catatan
Operator ?.
mengevaluasi operand sebelah kirinya tidak lebih dari sekali, menjamin bahwa operasi tidak dapat diubah menjadi null
setelah diverifikasi sebagai bukan null.
Operator akses anggota null-kondisional ?.
juga dikenal sebagai operator Elvis.
Pemanggilan delegasi utas-aman
Gunakan operator ?.
untuk memeriksa apakah delegasi merupakan bukan null dan panggil dengan cara utas-aman (misalnya, saat Anda menaikkan peristiwa), seperti yang ditunjukkan oleh kode berikut:
PropertyChanged?.Invoke(…)
Kode tersebut setara dengan kode berikut:
var handler = this.PropertyChanged;
if (handler != null)
{
handler(…);
}
Contoh sebelumnya adalah cara aman utas untuk memastikan bahwa hanya non-null handler
yang dipanggil. Karena instans delegasi tidak dapat diubah, tidak ada utas yang dapat mengubah objek yang dirujuk oleh variabel lokal handler
. Secara khusus, jika kode yang dijalankan oleh utas lain berhenti berlangganan dari peristiwa PropertyChanged
dan PropertyChanged
menjadi null
sebelum handler
dipanggil, objek yang dirujuk oleh handler
tetap tidak terpengaruh.
Ekspresi pemanggilan ()
Gunakan tanda kurung, ()
, untuk memanggil metode atau memanggil delegasi.
Contoh berikut menunjukkan cara memanggil metode, dengan atau tanpa argumen, dan memanggil delegasi:
Action<int> display = s => Console.WriteLine(s);
List<int> numbers =
[
10,
17
];
display(numbers.Count); // output: 2
numbers.Clear();
display(numbers.Count); // output: 0
Anda juga menggunakan tanda kurung saat memanggil konstruktor dengan operator new
.
Penggunaan lainnya dari ()
Anda juga menggunakan tanda kurung untuk menyesuaikan urutan untuk melakukan evaluasi operasi dalam ekspresi. Untuk informasi selengkapnya, lihat Operator C#.
Ekspresi konversi eksplisit, yang melakukan konversi jenis eksplisit, juga menggunakan tanda kurung.
Indeks dari operator akhir ^
Operator indeks dan rentang dapat digunakan dengan jenis yang dapat dihitung. Jenis yang dapat dihitung adalah jenis yang memiliki int
properti bernama atau Count
Length
dengan aksesor yang dapat diakses get
. Ekspresi koleksi juga mengandalkanjenis yang dapat dihitung.
Operator ^
menunjukkan posisi elemen dari akhir urutan. Untuk urutan panjang length
, ^n
menunjuk ke elemen dengan offset length - n
dari awal urutan. Misalnya, ^1
menunjuk ke elemen terakhir dari urutan dan ^length
menunjuk ke elemen pertama dari urutan.
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
Seperti yang ditunjukkan oleh contoh sebelumnya, ekspresi ^e
adalah berjenis System.Index. Dalam ekspresi ^e
, hasil dari e
harus secara implisit dapat dikonversi ke int
.
Anda juga dapat menggunakan operator ^
dengan operator rentang untuk membuat berbagai indeks. Untuk informasi selengkapnya, lihat Indeks dan rentang.
Dimulai dengan C# 13, Indeks dari operator akhir dapat digunakan dalam penginisialisasi objek.
Operator rentang ..
Operator ..
menentukan awal dan akhir rentang indeks sebagai operandnya. Operand sebelah kiri adalah awal rentang yang inklusif. Operand kanan adalah akhir rentang yang eksklusif. Salah satu operand dapat menjadi indeks dari awal atau dari akhir urutan, seperti yang ditunjukkan contoh berikut:
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));
Seperti yang ditunjukkan oleh contoh sebelumnya, ekspresi a..b
adalah berjenis System.Range. Dalam ekspresi a..b
, hasil dari a
dan b
harus secara implisit dapat dikonversi ke Int32 atau Index.
Penting
Konversi implisit dari int
ke Index
melempar ArgumentOutOfRangeException ketika nilainya negatif.
Anda dapat menghilangkan salah satu operand dari operator ..
untuk mendapatkan rentang terbuka:
a..
setara dengana..^0
..b
setara dengan0..b
..
setara dengan0..^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));
Tabel berikut ini memperlihatkan berbagai cara untuk mengekspresikan rentang pengumpulan:
Ekspresi operator rentang | Deskripsi |
---|---|
.. |
Semua nilai dalam koleksi. |
..end |
Nilai dari awal hingga secara end eksklusif. |
start.. |
Nilai dari secara start inklusif hingga akhir. |
start..end |
Nilai dari secara start inklusif ke end secara eksklusif. |
^start.. |
Nilai dari start secara inklusif ke penghitungan akhir dari akhir. |
..^end |
Nilai dari awal hingga penghitungan end eksklusif dari akhir. |
start..^end |
Nilai dari start secara inklusif hingga end dihitung secara eksklusif dari akhir. |
^start..^end |
Nilai dari start secara inklusif hingga end secara eksklusif keduanya dihitung dari akhir. |
Contoh berikut menunjukkan efek penggunaan semua rentang yang disajikan dalam tabel sebelumnya:
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
Untuk informasi selengkapnya, lihat Indeks dan rentang.
Token ..
juga digunakan sebagai operator spread dalam ekspresi koleksi.
Kelebihan beban operator
Operator .
, ()
, ^
, dan ..
tidak dapat kelebihan beban. Operator []
juga dianggap sebagai operator yang tidak boleh kelebihan beban. Gunakan pengindeks untuk mendukung pengindeksan dengan jenis yang ditentukan pengguna.
Spesifikasi bahasa C#
Untuk informasi selengkapnya, lihat bagian berikut dari spesifikasi bahasa C#:
Untuk informasi selengkapnya tentang indeks dan rentang, lihat catatan proposal fitur.
Lihat juga
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk