Na przykład:
public class Person
{
public Person()
{
}
~Person()
{
}
}
Kiedy powinienem ręcznie utworzyć destruktor? Kiedy musiałeś stworzyć destruktor?
c#
destructor
David Heffernan
źródło
źródło
Odpowiedzi:
AKTUALIZACJA: To pytanie było przedmiotem mojego bloga w maju 2015 roku . Dzięki za świetne pytanie! Na blogu znajduje się długa lista kłamstw, które ludzie powszechnie wierzą w finalizację.
Prawie nigdy.
Zazwyczaj jeden tworzy niszczyciel tylko wtedy, gdy klasa trzyma się jakiegoś drogiego niezarządzanego zasobu, który musi zostać wyczyszczony, gdy obiekt zniknie. Lepiej jest użyć wzorca jednorazowego, aby zapewnić oczyszczenie zasobu. Destruktor jest wówczas zasadniczo gwarancją, że jeśli konsument Twojego obiektu zapomni go zutylizować, zasoby nadal zostaną ostatecznie oczyszczone. (Może.)
Jeśli stworzysz destruktor, zachowaj szczególną ostrożność i zrozum, jak działa śmieciarz . Niszczyciele są naprawdę dziwne :
Prawie nic, co jest normalnie prawdziwe, nie jest prawdą w destruktorze. Bądź naprawdę bardzo ostrożny. Pisanie poprawnego destruktora jest bardzo trudne.
Podczas testowania części kompilatora, która obsługuje destruktory. Nigdy nie musiałem tego robić w kodzie produkcyjnym. Rzadko piszę obiekty, które manipulują niezarządzanymi zasobami.
źródło
Nazywa się to „finalizatorem” i zwykle powinieneś utworzyć tylko dla klasy, której stan (tj. Pola) zawiera niezarządzane zasoby (tj. Wskaźniki do uchwytów pobranych za pomocą wywołań p / invoke). Jednak w .NET 2.0 i nowszych istnieje lepszy sposób radzenia sobie z usuwaniem niezarządzanych zasobów: SafeHandle . Biorąc to pod uwagę, prawie nigdy nie powinieneś więcej pisać finalizatora.
źródło
Nie potrzebujesz go, chyba że klasa utrzymuje niezarządzane zasoby, takie jak uchwyty plików systemu Windows.
źródło
Nazywa się to destruktorem / finalizatorem i zwykle jest tworzony podczas implementacji wzorca Disposed.
Jest to rozwiązanie awaryjne, gdy użytkownik twojej klasy zapomina zadzwonić Dispose, aby upewnić się, że (w końcu) twoje zasoby zostaną uwolnione, ale nie masz żadnej gwarancji, kiedy wywoływany jest destruktor.
W tym pytaniu dotyczącym przepełnienia stosu zaakceptowana odpowiedź poprawnie pokazuje, jak zaimplementować wzorzec usuwania. Jest to potrzebne tylko wtedy, gdy klasa zawiera jakiekolwiek niezasłonięte zasoby, których śmieciarz nie zdoła sam się oczyścić.
Dobrą praktyką jest nie wdrażanie finalizatora bez umożliwienia użytkownikowi klasy ręcznego usunięcia obiektu w celu niezwłocznego uwolnienia zasobów.
źródło
Gdy masz niezarządzane zasoby i musisz się upewnić, że zostaną one wyczyszczone, gdy obiekt zniknie. Dobrym przykładem mogą być obiekty COM lub programy obsługi plików.
źródło
Użyłem destruktora (tylko do celów debugowania), aby sprawdzić, czy obiekt jest usuwany z pamięci w ramach aplikacji WPF. Nie byłem pewien, czy wyrzucanie elementów bezużytecznych naprawdę usuwa obiekt z pamięci, i to był dobry sposób na sprawdzenie.
źródło
Destruktory zapewniają niejawny sposób na uwolnienie niezarządzanych zasobów zamkniętych w twojej klasie, są wywoływane, gdy GC się do nich zbliża, i domyślnie wywołują metodę Finalize klasy podstawowej. Jeśli korzystasz z wielu niezarządzanych zasobów, lepiej jest zapewnić jawny sposób uwolnienia tych zasobów za pomocą interfejsu IDisposable. Zobacz przewodnik programowania w języku C #: http://msdn.microsoft.com/en-us/library/66x5fx1b.aspx
źródło