////je možné mít i strukturu ve struktuře (při použití je potřeba odpoznámkovat nastavení proměnné bod v konstruktoru) //public Bod bod; //konstruktor má stejné jméno jako struktura/třída //v konstruktoru musí být všechny členské proměnné ve struktuře přiřazené, pokud nejsou nepůjde kód přeložit public Bod3D(int x, int y, int z) { //slovo "this" (doslova toto/tato) určuje aktuální strukturu/třídu, ve které se konstruktor/metoda/členská-proměnná nachází //v aktuálním případě by se "this.x = x;" dalo přeložit jako "v této struktuře (tj. Bod3D) nastav členskou proměnnou 'x' na hodnotu vstupního parametru 'x'" //odlišení pomocí "this" je v tomto případě nutné, protože proměnné mají stejný název - jinak je možné napsat jen název členské proměnné, např. "ident" nemá v konstruktoru žádný jiný ekvivalent, takže je možné ho psát bez "this" (přesto se doporučuje this napsat pro lepší čitelnost a okamžitou informaci, že se jedná o členskou proměnnou nebo metodu) this.x = x; this.y = y; this.z = z; //použití statické metody v konstruktoru - statická metoda se používá zapsáním jména struktury/třídy a poté jejím jménem ident = Bod3D.RandomString(10); //pro nestatickou metodu //v případě použití nestatické metody se v konstruktoru při přiřazování identu rovnou z metody zobrazí chyba - nestatické metody je možné ve strukturách použít až když jsou nastaveny všechny členské proměnné, protože i v těchto metodách na ně můžete přístupovat a číst je //kompilátor nerozpozná, že tato metoda nijak neoperuje s členskými proměnnými a jen vrací string - pokud nevěříte, zapoznámkujte předchozí přiřazení do ident a nechte jen ten poslední ////ident = String.Empty; //pokud by bylo potřeba použít nestatickou metodu, je nutné první přiřadit všem členským proměnným nějakou hodnotu, např. prázdný string //ident = this.RandomStringNestatic(10); ////vytvoření bodu struktury Bod (při použití je potřeba odpoznámkovat proměnnou bod před konstruktorem) //bod = new Bod(); }
//metoda změní hodnoty zkopírované struktury, ale nic nezmění ve struktuře původní public static void ZměnaXYZ(Bod3D bod3D) { bod3D.x = 1; bod3D.y = 2; bod3D.z = 3; }
//metoda změní hodnoty originální struktury, jejiž místo v paměti je odkazováno pomocí magického vstupně/výstupně parametrického slůvka 'ref' public static void ZměnaXYZ(ref Bod3D bod3D) { bod3D.x = 100; bod3D.y = 200; bod3D.z = 300; }
static void Main(string[] args) { //vytvoření b1 struktury Bod (viz. soubor Bod.cs) - není nutné volat defaultní konstruktor s prázdnými parametry //protože se jedná o hodnotový typ a nikoli referenci, lze ji deklarovat a hodnoty nastavit přímo až poté Bod b1; b1.x = 2; b1.y = 3; //vzhledem k tomu, že má "zapovězenáProměnná" viditelnost "private" není možné se na ni dostat zvenčí //b1.zapovězenáProměnná = 0; Console.WriteLine("x, y ve struktuře \"Bod\": " + b1.x + ", " + b1.y); Console.WriteLine("\n"); //2 krát zařádkuje naprázdno - jednou pomocí zástupného zápisu \n a podruhé funkcí WriteLine //u struktury Bod3D pokud nepoužijeme konstruktor, není možné používat metody struktury (např. GetIdent) a také by se nenastaví členská proměnná ident (viz implementace konstruktoru v souboru Bod3D.cs) Bod3D vertex; vertex.x = 10; vertex.y = 20; vertex.z = 30; //zde ještě na metodu nemůžeme, protože nebyl zavolán konstruktor struktury Bod3D //vertex.GetIdent(); //zde bychom se na statickou metodu ve struktuře nedostali, protože má nastavenou viditelnost private - pokud bychom ji tedy chtěli použít museli bychom změnit viditelnost na public //string generovanyString = Bod3D.RandomString(10); Console.WriteLine("x, y, z ve struktuře \"Bod3D\" - zadáno bez konstruktoru: " + vertex.x + ", " + vertex.y + ", " + vertex.z); Console.WriteLine("\n"); //2 krát zařádkuje naprázdno - jednou pomocí zástupného zápisu \n a podruhé funkcí WriteLine vertex = new Bod3D(40, 50, 60); Console.WriteLine("x, y, z ve struktuře \"Bod3D\" - zadáno s konstruktorem: " + vertex.x + ", " + vertex.y + ", " + vertex.z); Console.WriteLine("Nyní se již na metodu GetIdent dostaneme: ident = \"" + vertex.GetIdent() + "\""); Console.WriteLine("\n"); //2 krát zařádkuje naprázdno - jednou pomocí zástupného zápisu \n a podruhé funkcí WriteLine //Při použití defaultního konstruktoru lze používat metody, ale pokud v konstruktoru nastavujete něco, co defaultně nastaveno nebude (v našem případě ident), může dojít k problémům //v našem případě dojde k problému při volání metody GetIdent, kde se testuje, zda je ident nastaven. Pokud nastaven není vyhodí se vyjímka. //házení vyjímek se provádí pomocí throw viz soubor Bod3D.cs v metodě GetIdent. Ošetřovat vyjímky jsme se už naučili (try-catch) vertex = new Bod3D(); Console.WriteLine("x, y, z ve struktuře \"Bod3D\" - zadáno s defaultním (prázdným) konstruktorem: " + vertex.x + ", " + vertex.y + ", " + vertex.z); try { Console.WriteLine("Nyní se již na metodu GetIdent dostaneme, ale hodí se nám v ní vyjímka, takže jdeme do catch: ident = \"" + vertex.GetIdent() + "\""); } catch (Exception ex) { //zobrazení zprávy, kterou hážeme ve vyjímce Console.WriteLine(ex.Message); } Console.WriteLine("\n"); //2 krát zařádkuje naprázdno - jednou pomocí zástupného zápisu \n a podruhé funkcí WriteLine //při předání struktury se v metodě hodnoty v paměti zkopírují ZměnaXYZ(vertex); Console.WriteLine("x, y, z ve struktuře \"Bod3D\" - Po zavolání metody ZměnaXYZ: " + vertex.x + ", " + vertex.y + ", " + vertex.z); Console.WriteLine("Nedošlo ke změně! (Proč, sí šarpe, proč?!) Protože se u vstupního parametru do metody kopíruje celá struktura."); Console.WriteLine("\n"); //2 krát zařádkuje naprázdno - jednou pomocí zástupného zápisu \n a podruhé funkcí WriteLine //předání pomocí ref umožňuje změnu v původní vstupní proměnné (bez kopírování - předává se reference) ZměnaXYZ(ref vertex); Console.WriteLine("x, y, z ve struktuře \"Bod3D\" - Po zavolání metody ZměnaXYZ s ref: " + vertex.x + ", " + vertex.y + ", " + vertex.z); Console.WriteLine("Díky použití \'ref\' došlo ke změně původních hodnot."); Console.WriteLine("\n"); //2 krát zařádkuje naprázdno - jednou pomocí zástupného zápisu \n a podruhé funkcí WriteLine List <Bod3D> a = new List <Bod3D>(); a.Add(vertex); //pozor na práci se strukturami v Listu, pro zápis zde nelze přistupovat rovnou k jednotlivým částem ve struktuře, protože se vrací kopie hodnotového typu (struktura) a ne reference na strukturu v Listu //tzn. nastavit napřímo členskou proměnnou ve struktuře nelze - zobrazí se chyba CS1612 "Vrácenou hodnotu List<Bod3D>.this[int] nejde změnit, protože se nejedná o proměnnou." //a[0].x = 400000; //pro vyřešení je nutné nejdříve zkopírovat strukturu do lokální proměnné, změnit členskou proměnnou a poté nahradit strukturu na indexu Listu Bod3D c = a[0]; c.x = 400000; a[0] = c; Console.WriteLine(vertex.x); Console.WriteLine(a[0].x); //tento zápis pro čtení proměnné nicméně projde, protože se nic nepřiřazuje (hodnotu jen čteme) Console.ReadKey(true); }