C# alaptípusokon kívül van értelme használni a ref kulcsszót paraméter átadásnál?
Mert ugye minden osztály referencia osztály és ahogy nézem semmit nem változtat a működésén, ha oda írom, hogy referencia, vagy sem.
Ha azt akarom, hogy az osztályom lemásolódjon paraméter átadásnál, akkor azt hogyan lehet elérni?
Van értelme még ha nem is egyértelmű elsőre :)
Ha ref kulcsszó nélkül adod át a paramétert akkor az osztály átadódik és mindenféle műveletet lehet végezni vele.
de ha new-al létrehozol egy ugyanilyen nevű osztályt a függvényen belül, ami a paraméterben van akkor nem ezt írod felül, hanem a stack-ban létrehozol egy új példányt, ami a a függvény elhagyásakor az enyészeté lesz és a régi él tovább a new előtti állapotban :)
Ha a ref-el adod át, akkor new esetén az eredeti példányt vágja felül, nem hoz létre újat a stackban.
vicces dolog ritkán kell ilyesmi.
Kérdés második fele: azt nem tudod. Ha mindenáron úgy akarod, akkor például ICloneable interface használatával és a Clone() hívással megvalósítható valamilyen szinten.
Egy egyszerű példa:
void Számol(int szám)
{
szám = 20;
}
void Számol2(ref int szám2)
{
szám2 = 20;
}
main metódus, kinek mi:
{
int a = 0;
Console.WriteLine(0);
Számol(a);
Console.WriteLine(a);
Számol2(ref a);
Console.WriteLine(a);
}
(a kódot ide írtam közvetlen, és sietek, a szintaktikai hibák miatt elnézést kérek, ha van)
Az a baj, hogy a pointerek működésének értése nélkül ezt nehéz lesz elmagyarázni, de valami fogalmad biztos van róla.
C#-ban sajnos eléggé meg van amúgy is kavarva az egész cucc azzal, hogy vannak külön referencia típusok és érték típusok.
Kezdjük ott, hogy ha csinálsz egy MyClass mc = new MyClass()-t, akkor az mc változó egy pointer memóriacímét tárolja, azaz csak azt tárolja, hogy a memóriában hol van az osztály.
Ha csinálsz egy MyStruct ms = new MyStruct()-ot, akkor az ms változód közvetlenül arra a címre mutat, ahol a memóriában a struct-od van.
Na most, vegyük azt, hogy a C#-ban csakis érték szerinti paraméter-átadás van, ugyanúgy, mint C-ben. Azaz az átadott paraméternek egy másolatával dolgozhatsz a függvényen belül.
Az, hogy az osztályok referencia szerint adódnak át, gyakorlatilag azt jelenti, hogy az osztályra mutató pointer másolatával dolgozol a függvényen belül. Azaz átadod mc-t, az lemásolódik, de mivel a másolat ugyanarra a példányra mutat a memóriában, módosíthatod a példány adattagjait, és nyilván ez reflektálódik az eredetileg mutatott osztály-példányon is.
De mivel a pointer másolatával dolgozol, ezért nem tudsz az eredeti, mc pointernek új értéket adni a függvényen belül, tehát az = new .., és az = null nem lesz hatással az eredeti mc mutatóra.
Ha ref-et használsz, akkor ténylegesen az eredeti pointerrel tudsz dolgozni a függvényen belül, de C-s analógiával úgy fogalmazhatunk, hogy egy, az eredeti mc pointerre mutató pointer másolatát kapod meg, azaz pl. egy MyClass**-ot, ha C++osan akarjuk írni.
Azaz tudod az eredeti pointer értékét változtatni, tehát az = new.., és az = null működnek, olyan értelemben, hogy a függvényen kívüli mc pointer-t egy újonnan létrehozott példányra tudod "átirányítani".
Van még az out kulcsszóval ellátott paraméter, de ez lényegében nem különbözik a ref-től, csak annyiban, hogy kötelező példányosítani a függvényen belül.
Sajnos C#-ban arra nincs mód, hogy az osztályod egy másolatát add át a függvénynek, legalábbis ilyen paraméter-átadási trükkökkel. Tehát meg kell írnod kézzel a másolást, és ehhez a bevett mód az ICloneable interface implementálása, azaz megírsz egy másoló logikát az osztályodnak.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!