Množina operátorů v jazyce C# je až na pár výjimek identická s operátory v jiných programovacích jazycích, jako je třeba Java. Následující tabulka uvádí přehled operátorů seřazených dle priority.
Tabulka 4.1. tabulka priority operátorů
Kategorie | Operátory |
---|---|
primární | (x) x.y f(x) a[x] x++ x-- new typeof sizeof checked unchecked |
unární | + - ! ~ ++x --x (T)x |
multiplikativní | * / % |
aditivní | + - |
bitové posuny | << >> |
relační | < > <= >= is as |
rovnost | == != |
logické AND (bitové) | & |
logické XOR (bitové) | ^ |
logické OR (bitové) | | |
AND | && |
OR | || |
podmíněný výraz | ? : |
přiřazení | = *= /= %= += -= <<= >>= &= ^= |= |
typeof - slouží k reflexi. Vrátí instanci třídy System.Type.
Type t = typeof(Console); foreach(MemberInfo info in t.GetMembers()) Console.WriteLine(info);
sizeof - slouží k zjištění velikosti hodnotových typů. Tato operace je považována za nebezpečnou a proto musí být tento operátor umístěn v bloku unsafe.
Definování bloku unsafe se explicitně zříkáme bezpečnostních kontrol prostředí .NET
Blok je definován pomocí klíčového slova unsafe a složenými závorkami.
Je nutné překladači povolit unsafe bloky (Project-Properties-Configuration Properties-Build-Allow Unsafe Code Blocks).
unsafe { Console.WriteLine("Size of int: {0}",sizeof(int)); }
Při porovnávání stringů pomocí operátoru == je porovnávána hodnota. Pokud chceme porovnat reference, musíme alespoň jeden řetězec přetypovat.
string a="hello"; string b="hello"; string c=String.Copy(a); Console.WriteLine(a==c); //True Console.WriteLine((object)a==(object)b); //True,same constant. Console.WriteLine((object)a==(object)c); //Flase
Pomocí operátoru is jsem schopni zjistit, zda je daný prvek instancí dané třídy, případně implementuje-li dané rozhraní.
if (someObject is SomeInterface) //vrátí true v případě, že someObject implementuje dané rozhraní { return someObject; } else { return null; } |
Operátor as provádí přetypování na daný typ. Pokud přetypování není možné, vrací null. Předvedený příklad by tedy šlo implementovat pomocí operátoru as takto:
return someObject as SomeInterface; |
C# 2.0 poskytuje nový operátor ?? nazvaný null splývající operátor (null coalescing operator) . Výsledek výrazu A ?? B je A, pokud je A non-nullable typu. Jinak je výsledek B. Pokud A obsahuje hodnotu null, tak B poskytne hodnotu k použití. Výraz A ?? B tedy vrací non-nullable hodnotu a poskytne vhodné implicitní přetypování:
int? x = GetNullableInt(); int? y = GetNullableInt(); int? z = x ?? y; int i = z ?? -1; |
Typ výrazu x ?? y je int?, ale výraz z ?? -1 je typu int. Operátor splývající null také funguje pro odkazové typy. Ukázka příkladu, kde program vypíše buď proměnnou s anebo, pokud je snull, vypíše Unspecified.
string s = GetStringValue(); Console.WriteLine(s ?? "Unspecified"); |
Ve verzi 2.0 v jazyce C# přibyl nový operátor ::. Pro minimalizaci nebezpečí záměny jmen je doporučováno používat plně kvalifikovaná jména (např. System.Console.WriteLine
místo Console.WriteLine
). Pokud se však v kódu vyskytuje například následující deklarace, použití plně kvalifikovaného jména nestačí.
int System, Console;
Tato deklarace efektivně znemožní vypisování čehokoliv na obrazovku. Nyní však můžete použít operátor ::
(dvě dvojtečky) pro přístup ke globálním jménům.
//this wont work System.Console.WriteLine("doesnot work!"); //this will work global::System.Console.WriteLine("works!");
Nutno upozornit, že funkce operátoru ::
je zde odlišná od jazyka C++. Je to binární operátor, na levé straně uvádíme obvykle slovo global
reprezentující globální prostor jmen, můžeme také uvést zástupné jméno prostoru jmen. V druhém případě má operátor ::
podobný význam jako operátor .
(tečka), avšak omezuje hodnotu na levé straně pouze na zástupná jména (namespace aliases).
Jazyc C# umožňuje přetěžování operátorů.
public static returnType operator op (object1 [,object2]) {...} |
Definice operátoru je vždy veřejná a statická. Následuje návratový typ. Obecně to může být libovolný typ. Klíčové slovo operátor určuje, že chceme přetížit operátor op. Přetěžujeme-li unární operátor definujeme jediný parametr. Pro operátory binární budou parametry dva. Na tyto parametry nejsou kladeny žádné omezení. Je vhodné, aby první parametr byl stejného typu jako třída, jejíž operátor přetěžujeme.
class Test { protected string text; public Test(string text) { this.text=text; } public string Text { get { return this.text; } set { this.text=value; } } public static Test operator + (Test t1,Test t2) { return new Test(t1.Text+","+t2.Text); } } class RunApp { public static void Main() { Test a=new Test("A"); Test b=new Test("B"); Test c=a+b; Console.WriteLine(c.Text); Console.WriteLine((a+b).Text); a+=b; Console.WriteLine(a.Text); } } |
Následující tabulka ukazuje, které operátory lze přetížit.
Slouží ke konverzi třídy nebo struktury do jiné třídy, struktury nebo základního typu. Typ, pro kterou je konverze definovaná, se musí objevit buď v parametru nebo musí konverze tento typ vracet a opět (podobně jako u operátorů) musí být definice veřejná a statická.Jsou dva druhy uživatelsky definovaných konverzí:
implicitní - jsou prováděny aniž by uživatel musel cokoliv zadávat;
explicitní - uživatel misí zadat, že chce provést konverzi.
public static implicit operator type(object) public static explicit operator type(object) |
Použití demonstruje následující příklad:
class Test { protected string text; public string Text { get { return this.text; } set { this.text=value; } } public static implicit operator Test(string a) { Test t=new Test(); t.Text=a; return t; } public static explicit operator string(Test a) { return a.Text; } } class RunApp { public static void Main() { Test a="hello"; //implicit conversion string b=(string)a; //explicit conversion } } |