Jen tak pro upřesnění: GC funguje tak, že prochází reference od rootu a u každé "si udělá čárku" - tím zjistí, kam se dá dostat a co je mrtvé (reference bez "čárky") No a ty disposne. Provádí se to každou volnou chvilku (což je dobré vědět, proto například "GC.Collect(); nejakydlouhyukol();" ve skutečnosti nevyvolá kolekci mrtvolek před nejakydlouhyukol() - myslím že je tam jakýsi parametr který vyvolá kolekci synchronně či přímo metoda, nevzpomínám si přesně :) )
-----------------------
Co je ale velký problém tohoto článku je právě to NEW... Omg, když mluvíš o OOP a jako příklad uvádíš NEW... To je strašně matoucí.
Zkus si například toto:
Dog pes = new Dog("Hafík");
((Animal)pes).Shout();
Co se stane? Jeje, pejsek nás pozdraví, i když měl značkovat. Což je problém:
Person
{
List<Animal> _pets = new List<Animal>();
public void AddPet(Animal pet)
{
_pets.Add(pet);
}
public void AllPetsShout()
{
foreach(Animal pet in _pets)
pet.Shout();
}
}
V tomhle případě veškerá zvířata budou pouze zdravit (implementace z Animal), ať si pomocí "new" přepíšu metodu jak chci.
Správně by to mělo být virtual/override či dokonce abstract/override. A co třeba sealed? Volání base() v metodě a nejen konstruktoru? :-/
To co uvádíš, má sice NĚKDY smysl, ale z několikaleté profesionální praxe to používáš jen pokud odvozuješ od třídy z .dll u které nemáš přístup k zdrojákům a pak to ještě složitě voláš, jinak si koleduješ o malér (který je naštěstí pěkně vidět na callstacku, ale musíš vědět co hledáš). Ano, jde to, ale je to hnus.
A hlavně neříkej, že ukazuješ jen "začátek OOP", protože tohle je fakt špatný příklad na začátek. Virtual/override je také jednoduché a funguje korektně. |