A konstans
Ha azt szeretnĂ©nk, hogy egy primitĂv (beĂ©pĂtett tĂpusĂş) vagy enum változĂł Ă©rtĂ©ke ne tudjon mĂłdosulni, hanem az egĂ©sz programra nĂ©zve ugyanaz legyen mindig, akkor azt a változĂłt meg kell jelölni a const kulcsszĂłval.
Bizonyos szinten ellentmondás az, hogy egy változó konstans. Most változik az értéke vagy sem?
Ez viszont csak a “változó” / “variable” elnevezĂ©s miatt van Ăgy. Pontosabban leĂrná a fogalmat, ha Ăşgy hĂvnánk a változĂłt, hogy “NevesĂtett objektum tároló”. Ennek azonban sajnos nem olyan jĂł a csengĂ©se. EzĂ©rt marad a változĂł, ami csak akkor hangzik furán ha Ă©ppen az konstans.
(Lokális változók és field-ek is lehetnek konstansok.)
Egy konstans változĂł csak egyszer van eltárolva a memĂłriában szemben a normál mezĹ‘kkel, amik annyiszor lĂ©teznek, ahány pĂ©ldány lĂ©tezik az Ĺ‘ket tartalmazĂł összetett tĂpusbĂłl.
Vegyük a következő példát:
A fenti kĂłd leĂr egy Person (szemĂ©ly) osztályt. Minden szemĂ©lynek van egy neve Ă©s egy kora.
Mivel 5 szemĂ©lyt hoztam lĂ©tre ebbĹ‘l az osztálybĂłl, Ăgy 5 kĂĽlönbözĹ‘ kor változĂł lĂ©tezik a memĂłriában. Minden szemĂ©lyhez egy.
Azonban a nagykorĂşság korhatára egy fix Ă©rtĂ©k, mindenkire ugyanĂşgy igaz. Nem Ă©rdemes többször eltárolni Ă©s nem tartozik csak egy szemĂ©lyhez. EzĂ©rt osztályon kĂvĂĽlrĹ‘l nem az objektum-on, hanem az osztály nevĂ©n keresztĂĽl tudunk hivatkozni rá:
// Normál mező:
int ageOfLisa = person4.age; // Hivatkozás egy példányon keresztül
// Konstans:
int limitAge = Person.adulthoodAgeLimit; // Hivatkozás az osztály nevĂ©n keresztĂĽlMindebben a konstans “változó” nagyban hasonlĂt egy statikus tagra.
Látsd: Statikus tagok és osztályok
readonly: A csak olvasható mező
Konstansokat csak a C# beĂ©pĂtett (primitĂv) tĂpusaibĂłl Ă©s enum-okbĂłl tudunk lĂ©trehozni.
Minden egyĂ©b tĂpusbĂłl hasonlĂł cĂ©lra Ă©rdemes lehet egy readonly, azaz csak olvashatĂł mezĹ‘t használni. Ezen fajta változĂłnak csak egyszer az objektum lĂ©trejöttekor adhatunk Ă©rtĂ©ket, ami aztán nem változhat. Ezt tehetjĂĽk közvetlen Ă©rtĂ©kadással (a deklaráciĂłval egy sorban) vagy konstruktorral:
// Létrehozok két readonly vektort,
// amik egység hosszúak és 45 fokos szöget zárnak be minden tengellyel:
// Értékadás egyből deklarációvan egy sorban.
readonly Vector2 diagonal2 = new (1/Mathf.Sqrt(2), 1/Mathf.Sqrt(2));
// Értékadás konstruktorral:
readonly Vector3 diagonal3;
TestClass() // Konstruktor
{
float d = 1 / Mathf.Sqrt(3);
diagonal3 = new (d, d, d);
}Gyakran a readonly változó egyben static is. Ekkor gyakorlatilag konstansként viselkedik.
LehetsĂ©ges statikus osztályokban statikus konstruktort is Ărni, ami egyszer fog lefutni mielĹ‘tt elĹ‘ször használnánk az osztályt. Ebben beállĂthatjuk az ilyen elemek Ă©rtĂ©keit. Pl.:
static class MyMath
{
public static readonly Vector2 diagonal2;
public static readonly Vector3 diagonal3;
MyMath() // statikus konstruktor
{
float d2 = 1 / Mathf.Sqrt(2);
diagonal2 = new (d3, d3);
float d3 = 1 / Mathf.Sqrt(3);
diagonal3 = new (d3, d3, d3);
}
}