Tento díl bude o odkazových a hodnotových proměnných, escape sekvencích a také se malinko koukneme na boxing, je toho dost, tak teď nezbývá, než si to celé přečíst...
Proměnné odkazové a hodnotové
Jazyk C#, jako každý z rodiny .net, má zabudovaný systém ochrany typů (proměnné definované v jednom jazyce mají stejnou platnost v libovolném jiném jazyce). Proměnné jsou deklarovány a existují jako určitý typ, a tak smí uchovávat pouze hodnoty, pro které byly deklarovány. Pravdou ale také je, že proměnné mohou uchovávat i jiné odkazové a hodnotové typy, ovšem musejí to být ukazatelé (pointery), ty budou blíže popsány v dalším díle.
Stručně, rozdíl mezi hodnotovým typem a odkazovým (referencí):
- pokud je proměnná hodnotovým typem, obsahuje objekt s nějakou hodnotou a žádná jiná proměnná k tomuto objektu nemá přístup (ačkoliv jiná proměnná může nabýt stejnou hodnotu)
- pokud je proměnná referencí, obsahuje odkaz, který směřuje k nějakému objektu. Jiná proměnná může obsahovat odkaz ke stejnému objektu.
Hodnotové typy
I v C# je možné si nadefinovat vlastní datový typ nebo strukturu, o tom někdy jindy. Tyto uživatelsky definované proměnné jsou kompilátorem upraveny úplně stejně jako ty předdefinované základní typy, akorát jsou upraveny později. Všechny typy jsou odvozeny od základního objektu, hlavně toto umožňuje ochranu typů (v praxi to ale oceníte jen v případě, že děláte ve více jazycích z platformy .net ). Následuje tabulka předdefinovaných hodnotovým typů:
C# Typ | .Net Framework (System) typ | znaménkový? | velikost v bytech | rozsah |
---|---|---|---|---|
sbyte | System.Sbyte | A | 1 | -128 až 127 |
short | System.Int16 | A | 2 | -32768 až 32767 |
int | System.Int32 | A | 4 | -2147483648 až 2147483647 |
long | System.Int64 | A | 8 | -9223372036854775808 až 9223372036854775807 |
byte | System.Byte | N | 1 | 0 až 255 |
ushort | System.Uint16 | N | 2 | 0 až 65535 |
uint | System.UInt32 | N | 4 | 0 až 4294967295 |
ulong | System.Uint64 | N | 8 | 0 až 18446744073709551615 |
float | System.Single | A | 4 | ± 1.5 x 10-45 to ±3.4 x 1038 se 7 desetinnými místy |
double | System.Double | A | 8 | ± 5.0 x 10-324 to ±1.7 x 10308 s 15 nebo 16 desetinnými místy |
decimal | System.Decimal | A | 12 | ±1.0 x 10-28 to ±7.9 x 1028 s 28 nebo 29 desetinnými místy |
char | System.Char | jiný | 2 | jakýkoli Unicode znak (16 bit) (znakový typ) |
bool | System.Boolean | jiný | 1 / 2 | true (pravda) or false(lež) |
Zde jsou deklarovány dvě proměnné a nastaveny v rozsahu typu integer:
int x = 10;
int y = x;
y = 20; // poté má x hodnotu 10 a y hodnotu 20
Referenční typy
Předdefinované referenční typy jsou object a string, typ object byl zmíněn výše, je to základní třída všech ostatních typů. Nové reference mohou být užívány v deklaracích class, interface a delegate. Reference je odkaz na místo v paměti, kde se nalézá daný objekt a z toho je získána hodnota. V následujícím příkladě získají 2 proměnné referenci na stejný objekt (pro přehlednost, objektem je obsah vlastnosti "myValue"):
object x = new object();
x.myValue = 10;
object y = x;
y.myValue = 20; // nakonec se x.myValue a y.myValue rovnají 20
Tento kus kódu ukazuje, že změna provedena s nějakou referencí se odrazí i v jiné, pokud ukazuje na stejný objekt, je nutné si uvědomit, že reference je jen odkazem, a když budete mít 50 referecí na jeden objekt, bude mít všech 50 stejnou hodnotu, protože objekt a tím pádem i hodnota je jen jeden (jedna :) ). Drobnou vyjímkou mezi referencemi je datový typ string, protože se na první pohled chová spíše jako hodnotový typ a tak je i používán:
string s1 = "hello";
string s2 = s1;
Teď mají s1 a s2 stejnou hodnotu "hello", ale když provedete něco nekalého, :)
s1 = "goodbye";
tak se s1 = "goodbye", ale s2 = "hello". Jak je to možné? Ano, tušíte správně. Je v tom malý trik, protože proměnné typu string jsou imunní reference a jejich hodnota nesmí být po vytvoření měněna, tak se při změně hodnty z "hello" na "goodbye" vytvořil nový objekt, na který odkazuje s1, ale s2 zůstala ukazovat na ten starý s hodnotou "hello". No snad se z toho nezamotáte, raději už ty referenční proměnné ukončíme...
Escape sekvence a Verbatim řetězce
Aneb když potřebuje psát to, co je normálně součástí syntaxe. Jak napsat text s uvozovkymi a ještě ho zalomit?:
string a = ""Hello WorldnHow are you"";
výsledek:
"Hello World
How are you"
další escape sekvence:
Character | Escape Sequence |
---|---|
' | ' |
" | " |
\ | |
Alert | a |
Backspace | b |
Form feed | f |
New Line | n |
Carriage Return | r |
Horizontal Tab | t |
Vertical Tab | v |
An Unicode character specified by its number e.g. u200 | u |
An Unicode character specified by its hexidecimal code e.g. xc8 | x |
null |