A C#-ban a következő típusok találhatók:
int a = 35; double b = 35.43;
Bármely programozási nyelvet használjuk az elindított program számára memóriát foglalunk le. Ez a memória minden folyamat számára két részre van osztva. Van egy verem terület és egy halom terület.
A referencia egy olyan változó, amely valójában csak egy mutató egy objektumra. A C# nyelvben ilyen referenciákat az osztályokból alkotott „változók” valósítják meg. Tegyük fel, hogy van egy Dolgozo nevű osztályunk, és annak van három tagja: nev, kor, fizetes. Létrehozunk belőle egy joska nevű példányt. Amikor leírom Dolgozo joska; akkor a verem területen létre jön egy hivatkozás (referencia), amely majd a tagokra mutat. A tagok (nev, kor, fizetes) a halom területen lesznek tárolva.
Dolgozo joska; // Helyet foglalunk a referenciának joska = new Dolgozo(); // Helyet foglalunk az objektumnak
A C# lehetővé teszi a C és Pascal nyelvből jól ismert mutató típusok használatát. A használata azonban nem biztonságos kategóriába tartozik. Nem is lehet csak úgy használni, ha unsafe módosítót használjuk, /unsafe fordítói kapcsolóval együtt. A C# lévén C alapú nyelv, a C nyelv szintaktikája alapján adjuk meg a mutató típusú változót.
A mutatóban érték helyett egy címet tárolunk el. Például egy másik változó címét. A C# nyelvben a mutató típusú változó neve elé egy „*” karaktert teszünk deklaráláskor és definiáláskor is.
int *p;
Ha egy normál változónak a címét le szeretném kérdezni, a változó neve elé tett „&” jel karakterrel jelzem.
&a
Mindezek fényében értelmes kifejezés a következő:
int *p = &a;
Az a változó címét átadom a p mutatónak. A p mutató így mindig a tartalmára mutat.
Teljes kód:
using System; class Program01 { public static unsafe void Main() { int a = 35; int *p = &a; Console.WriteLine(*p); } }
A metódust amelyben használjuk a mutatót meg kell jelölni az unsafe módosítóval. A fordításhoz szükség van a /unsafe kapcsolóra.
Vegyük észre, ha a mutató típusú változó által mutatott értéket szeretném kiíratni, akkor „*” karaktert teszünk a mutató típusú változó neve elé.
Egyszerű regex:
using System.Text.RegularExpressions; //... public bool IsValid(string value) { return Regex.IsMatch(value, @"^[0-9]*$"); }
Egy metódusban a paramétereket két módon adhatjuk át:
Ha egy paraméter érték szerint lett átadva, a metódus formális paraméterlistájában szereplő változó változása semmilyen hatással nincs a metódus aktuális paramétereként megadott változóra.
Ha a metódus paramétere cím szerint (referenciaként) van átadva, akkor a metódus formális paraméterének változása, hatással van az aktuális paraméterként megadott változóra is.
Egy szimplán megírt metódus a C# nyelvben érték szerinti paraméterátadást valósít meg. Ha a paramétert cím szerint (referenciaként) szeretnénk átadni, akkor a ref vagy az out kulcsszót kell a típus elé tenni a metódus formális paraméterében, és az aktuális paraméterként átadott változó elé is, mint az a következő példa is mutatja.
using System; class Program01 { static void csinal1(int a) { a = 1; } static void csinal2(ref int a) { a = 2; } static void csinal3(out int a) { a = 3; } static void Main() { int b = 0; csinal1(b); Console.WriteLine(b); csinal2(ref b); Console.WriteLine(b); csinal3(out b); Console.WriteLine(b); } }
Figyeljük meg, hogy az aktuális paraméterként mindenhol 0 lesz átadva a függvények. Az csinal1() metódus nem változtatja meg „b” értékét, de csinal2() és a csinal() már igen.
Mi a különbség a ref és az out között? Mindkét esetben a paraméter változó értékének megváltoztatása hatással van a hívás helyére. A különbség abban áll, hogy az out esetén a hívás helyén felhasznált változó értékének nem kötelező kezdőértéket adni.
using System; class Program01 { static void csinal2(ref int a) { a = 2; } static void csinal3(out int a) { a = 3; } static void Main() { int b = 0; int c; csinal2(ref b); Console.WriteLine(b); csinal3(out c); Console.WriteLine(c); } }
A tömb átadása is cím szerint történik:
using System; class Program01 { static void csinal(int[] tomb) { tomb[1] = 9; } static void Main() { int[] tomb = {8, 4, 3}; csinal(tomb); Console.WriteLine(tomb[1]); } }
Ha objektumot adunk át, az szintén cím szerint történik, mivel az eleve referencia.
using System; class Dolgozo { public String nev; public int kor; } class Program01 { static void csinal(Dolgozo dol) { dol.nev = "Mike"; } static void Main() { Dolgozo joska = new Dolgozo(); joska.nev = "Névtelen"; csinal(joska); Console.WriteLine(joska.nev); } }
A fenti program kimenet „Mike”, mivel felülírtuk a csinal() metódusban.
Egy program két módon érhet véget. Vagy ez a szándék, vagy valamilyen hiba történt. Ha sikerült elkapni a hibát, akkor mi magunk utasíthatjuk a programot, a kilépésre, saját hibaüzenet generálva.
Ugyanakkor minden program visszatér kilépéskor egy számmal. Ha a program hiba nélkül lépett ki, ez a szám 0. Hiba esetén a 0-tól eltérő számmal illik kiléptetni a programot. A szám utalhat a hiba típusára, vagy azonosíthatja is azt.
A C# nyelven kilépés:
System.Environment.Exit(0);
Hol van szerepe a visszatérési értéknek? A program az operációs rendszer egyik környezeti változójába helyezi el a visszatérési értéket. A program futtatása után ez az érték lekérdezhető.