Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Pro přístup k členu typu použijete několik operátorů a výrazů. Operátory přístupu členů zahrnují přístup člena (.), prvek pole nebo přístup indexeru ([]), index-from-end (^), rozsah (..), operátory s podmínkou null (?. a ?[]) a vyvolání metody (()). Mezi tyto operátory patří operátory přístupu členů s podmínkou null (?.) a přístup indexeru (?[]).
.(přístup člena): k přístupu k prvku oboru názvů nebo typu[](přístup k elementu pole nebo indexeru):: přístup k prvku pole nebo indexeru typu?.a?[](null-podmíněné operátory): pro provedení operace přístupu ke členovi nebo prvku pouze v případě, že operand nemá hodnotu null.()(vyvolání): volání přístupové metody nebo vyvolání delegáta^(index od konce): označuje, že pozice prvku je od konce posloupnosti...(rozsah): určení rozsahu indexů, které můžete použít k získání rozsahu sekvenčních prvků
Výraz přístupu člena .
Token . použijete k přístupu k členu oboru názvů nebo typu, jak ukazují následující příklady:
- Pomocí
.přistupujete ke vnořenému oboru názvů v rámci oboru názvů, jak ukazuje následující příklad direktivyusingusing:
using System.Collections.Generic;
- Použijte
.k vytvoření kvalifikovaného názvu pro přístup k typu v rámci jmenného prostoru, jak je znázorněno v následujícím kódu.
System.Collections.Generic.IEnumerable<int> numbers = [1, 2, 3];
Použijte direktivu c1, aby bylo použití kvalifikovaných názvů volitelné.
- Použijte
.pro přístup ke členům typu, statickým a nestatickým, jak ukazuje následující kód:
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
Můžete také použít . přístup k členu rozšíření.
Indexovací operátor []
Hranaté závorky [] se obvykle používají pro přístup k prvkům pole, indexeru nebo ukazatele. Počínaje verzí C# 12, [] uzavírá výraz kolekce.
Přístup k poli
Následující příklad ukazuje přístup k prvkům pole:
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
Pokud je index pole mimo hranice odpovídající dimenze pole, dojde k vyhození IndexOutOfRangeException.
Jak ukazuje předchozí příklad, použijete také hranaté závorky, když deklarujete typ pole nebo vytvoříte instanci pole.
Další informace o polích naleznete v tématu Pole.
Přístup k indexeru
Následující příklad používá typ .NET Dictionary<TKey,TValue> k předvedení přístupu indexeru:
var dict = new Dictionary<string, double>();
dict["one"] = 1;
dict["pi"] = Math.PI;
Console.WriteLine(dict["one"] + dict["pi"]); // output: 4.14159265358979
Indexery umožňují indexovat instance uživatelem definovaného typu podobným způsobem jako indexování pole. Na rozdíl od indexů pole, které musí být celé číslo, lze parametry indexeru deklarovat jako jakýkoli typ.
Další informace o indexerech naleznete v tématu Indexery.
Další využití []
Informace o přístupu k prvkům ukazatele naleznete v části Operátor přístupu k prvku ukazatele [] oddílu Operátory související s ukazatelem článku. Informace o výrazech kolekce naleznete v článku o výrazech kolekce.
Také používáte hranaté závorky k určení atributů:
[System.Diagnostics.Conditional("DEBUG")]
void TraceMethod() {}
Hranaté závorky lze také použít k určení vzorů seznamu pro použití při porovnávání vzorů nebo testování.
arr is ([1, 2, ..])
//Specifies that an array starts with (1, 2)
Operátory podmíněné na hodnotu null ?. a ?[]
Podmíněný operátor pro hodnoty null použije operaci přístupu ke členu (?.) nebo přístupu k elementu (?[]) na svůj operand pouze v případě, že se tento operand vyhodnotí jako nenulový; v opačném případě vrátí null. Jinými slovy:
Pokud
ase vyhodnotí jakonull, výsledeka?.xneboa?[x]jenull.Pokud
se vyhodnotí na nenulovou hodnotu, výsledek nebo je stejný jako výsledek nebo Poznámka:
Pokud
a.xneboa[x]vyvolá výjimku,a?.xneboa?[x]by vyvolalo stejnou výjimku pro nenulovýa. Pokud je napříkladainstance pole, která není null, axje mimo hranicea,a?[x]by vyvolal výjimku IndexOutOfRangeException.
Operátory s podmínkou null mají vlastnost krátkého obvodu. To znamená, že pokud jedna operace v řetězci podmíněného přístupu k členovi nebo prvku vrátí null, zbytek řetězce se nespustí. V následujícím příkladu se nevyhodnocuje B, pokud se A vyhodnotí na null, a C se nevyhodnocuje, pokud se A nebo B vyhodnotí na null:
A?.B?.Do(C);
A?.B?[C];
Pokud A může být null, ale B a C by nebyly null, pokud A není null, stačí aplikovat podmíněný operátor null na A:
A?.B.C();
V předchozím příkladu se B nevyhodnocuje a C() není volána, pokud má A hodnotu null. Pokud je však přístup zřetězeného člena přerušen, například závorky jako v (A?.B).C()případě , zkratování se nestane.
Následující příklady ukazují použití operátorů ?. a ?[]:
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}");
}
První předchozí příklad také používá operátor ??koalescenčního operátoru null k určení alternativního výrazu pro vyhodnocení v případě, že výsledek null-podmíněné operace je null.
Pokud a.x nebo a[x] je typu hodnoty, která je nenulovatelná, T, a?.x nebo a?[x] je odpovídající nulovatelný typ hodnoty T?. Pokud potřebujete výraz typu T, použijte operátor ?? na výraz podmíněný nulou, jak ukazuje následující příklad:
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
Pokud v předchozím příkladu nepoužijete operátor ??, numbers?.Length < 2 se vyhodnotí na false , když je numbersnull.
Poznámka:
Operátor ?. vyhodnotí levý operand maximálně jednou a zaručuje, že jej nelze změnit na null poté, co byla ověřena, že není null.
Počínaje jazykem C# 14 je přiřazení přípustné s výrazem podmíněného přístupu s hodnotou null (?. a ?[]) pro odkazové typy. Podívejte se například na následující metodu:
person?.FirstName = "Scott";
messages?[5] = "five";
Předchozí příklad ukazuje přiřazení vlastnosti a indexovaný prvek u typu odkazu, který může mít hodnotu null. Důležité chování tohoto přiřazení spočívá v tom, že výraz na pravé straně = je vyhodnocen pouze v případě, že je známo, že levá strana není nulová. Například v následujícím kódu se funkce GenerateNextIndex volá pouze v případě values , že pole nemá hodnotu null. Pokud je pole values null, GenerateNextIndex není voláno:
values?[2] = GenerateNextIndex();
int GenerateNextIndex() => index++;
Jinými slovy, předchozí kód je ekvivalentní následujícímu kódu pomocí if příkazu pro kontrolu null:
if (values is not null)
{
values[2] = GenerateNextIndex();
}
Kromě přiřazení je povolena jakákoli forma složeného přiřazení, například += nebo -=. Přírůstky () a dekrementace (++--) ale nejsou povolené.
Toto vylepšení neklasifikuje podmíněný výraz null jako proměnnou. Nelze ji ref přiřadit, ani ji nelze přiřadit do ref proměnné, ani ji předat metodě jako ref argument out.
Vyvolání delegáta bezpečného pro přístup z více vláken
Pomocí operátoru ?. zkontrolujte, jestli delegát není null a zavolejte ho vláknově bezpečným způsobem (například při vyvolání události), jak ukazuje následující kód:
PropertyChanged?.Invoke(…)
Tento kód je ekvivalentní následujícímu kódu:
var handler = this.PropertyChanged;
if (handler != null)
{
handler(…);
}
Předchozí příklad představuje bezpečný způsob, jak zajistit, že se vyvolá pouze nenulová handler hodnota. Vzhledem k tomu, že instance delegátů jsou neměnné, žádné vlákno nemůže změnit objekt, na který odkazuje místní proměnná handler. Zejména pokud kód spuštěný jiným vláknem odhlásí PropertyChanged událost a PropertyChanged se stane null před vyvoláním handler, objekt odkazovaný handler zůstane nedotčen.
Výraz vyvolání ()
K volání metody nebo vyvolání delegáta použijte závorky ().
Následující kód ukazuje, jak volat metodu s argumenty nebo bez argumentů a vyvolat delegáta:
Action<int> display = s => Console.WriteLine(s);
List<int> numbers =
[
10,
17
];
display(numbers.Count); // output: 2
numbers.Clear();
display(numbers.Count); // output: 0
Při vyvolání konstruktoru operátorem new také použijete závorky.
Další využití ()
Pomocí závorek také upravíte pořadí, ve kterém se mají vyhodnocovat operace ve výrazu. Další informace najdete v tématu Operátory jazyka C#.
Výrazy přetypování, které provádějí explicitní převody typů, také používají kulaté závorky.
Index od koncového operátoru ^
Operátory indexu a rozsahu lze použít s typem, který je spočetný. Počitatelný typ je typ, který má vlastnost s názvem buď Count nebo Length s přístupovou metodou get. Výrazy kolekce také spoléhají na počitatelné typy.
Poznámka:
Jednorozměrná pole jsou počítáná. Multidimenzionální pole nejsou. Operátory ^ a .. (rozsah) nelze použít v multidimenzionálních polích.
Operátor ^ označuje pozici prvku od konce sekvence. Pro sekvenci délky length, ^n ukazuje na prvek s posunem length - n od začátku sekvence. Například ^1 ukazuje na poslední prvek sekvence a ^length ukazuje na první prvek sekvence.
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
Jak ukazuje předchozí příklad, výraz ^e je typu System.Index. Ve výrazu ^e, musí být výsledek e implicitně konvertibilní na int.
Můžete také použít operátor ^ společně s operátorem rozsahu k vytvoření rozsahu indexů. Další informace naleznete v Indexy a rozsahy.
Počínaje jazykem C# 13 lze index z koncového operátoru použít v inicializátoru objektů.
Operátor rozsahu ..
Operátor .. určuje začátek a konec rozsahu indexů jako operandy. Levý operand je inkluzivním začátkem rozsahu. Pravý operand je exkluzivním koncem rozsahu. Jeden z operandů může být indexem od začátku nebo od konce sekvence, jak ukazuje následující příklad:
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));
Jak ukazuje předchozí příklad, výraz a..b je typu System.Range. Ve výrazu a..b, výsledky a a b musí být implicitně konvertibilní na Int32 nebo Index.
Důležité
Implicitní převody z int na Index vyvolají ArgumentOutOfRangeException, když je hodnota záporná.
Pokud chcete získat otevřený rozsah, můžete vynechat kterýkoli z operandů .. operátoru.
-
a..je ekvivalentnía..^0 -
..bje ekvivalentní0..b -
..je ekvivalentní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));
Následující tabulka ukazuje různé způsoby vyjádření rozsahů kolekcí:
| Výraz operátoru rozsahu | Popis |
|---|---|
.. |
Všechny hodnoty v kolekci. |
..end |
Hodnoty od začátku výhradně do end. |
start.. |
Hodnoty od start včetně do konce. |
start..end |
Hodnoty od start včetně do end bez. |
^start.. |
Hodnoty od start včetně až po konec, počítáno od konce. |
..^end |
Hodnoty od začátku po end bez zahrnutí konce. |
start..^end |
Hodnoty od start inkluzivně po end exkluzivně, počítajících od konce. |
^start..^end |
Hodnoty od start inkluzivního po end výhradně oba počítání od konce. |
Následující příklad ukazuje účinek použití všech oblastí uvedených v předchozí tabulce:
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
Další informace naleznete v Indexy a rozsahy.
Token .. se také používá pro prvek 'spread' ve sběrovém výrazu.
Přetížení operátoru
Operátory ., (), ^, a .. nelze přetížit. Operátor [] je také považován za nepřetížitelný operátor. Použijte indexátory k podpoře indexování s uživatelsky definovanými typy.
specifikace jazyka C#
Další informace najdete v následujících částech specifikace jazyka C#:
Další informace o indexech a rozsazích najdete v poznámce k návrhu funkce .