MSDN's example pattern dla wdrożenia do utylizacji() Metoda przedstawia ustawianie odniesienia do nastawionej zarządza zasobami null (_resource = null
), lecz nie tak zewnątrz bloku if (disposing)
:MSDN Dispose() przykład błędne? (Kiedy ustawić zarządzanych odniesienia do NULL)
protected virtual void Dispose(bool disposing)
{
// If you need thread safety, use a lock around these
// operations, as well as in your methods that use the resource.
if (!_disposed)
{
if (disposing) {
if (_resource != null)
_resource.Dispose();
Console.WriteLine("Object disposed.");
}
// Indicate that the instance has been disposed.
_resource = null;
_disposed = true;
}
}
shouldn 't _resource = null
należy umieścić w tym bloku kodu? Jeśli zostanie wykonane połączenie z numerem Dispose(false)
, wówczas _resource
będzie mieć wartość null i nie będzie można go później usunąć! ??
Oczywiście, Dispose(false)
jest wywoływany tylko (w praktyce) przez środowisko wykonawcze podczas finalizacji. Ale jeśli _resource
nie został wcześniej usunięty, jaka jest potrzeba ustawienia go na wartość null w tym momencie, gdy obiekt (w tym pole członkowskie _resource
) zostanie wkrótce zebrany?
[koniec pierwotnego pytania]
Kontynuacja:
Po wielu czytanie wydaje się ustawienie odniesienie do wartości null nie jest konieczne, ale może być dobrym pomysłem dla „ciężkiego” członka obiekty, jeśli masz powody, by sądzić, że klasa zawierająca (ta, która została usunięta) może wkrótce nie zostać wyrzucona do śmieci.
Wiedz o tym, że likwidacja obiektu nie gwarantuje, że obiekt został "zwolniony" po zużyciu kodu. Wyrzucony przedmiot może być trzymany (w zbiorze lub w inny sposób) do różnych celów lub po prostu w wyniku błędu. Mogę sobie wyobrazić, że aplikacja korzystająca z obiektów z kolekcji usuwa je, ale przechowuje w kolekcji dla późniejszego procesu usuwania i stanu końcowego rejestracji (lub czegoś podobnego ... kto wie ...)
Wnioski:
- Ustawianie odniesienia do „ciężkich” obiektów członkowskich null wydaje je do zbierania śmieci, nawet jeśli umieszczone obiekt nie zostanie zwolniony.
- Przesadą jest usuwanie referencji dla wszystkich obiektów.
- Dlatego umieszczenie instrukcji
_resource = null
(pierwotne pytanie) nie jest ważne z dwóch powodów: (A) Korzystanie z niego w ogóle jest tylko kwestią do przemyślenia po przeczytaniu powyższego; (B) W przykładzie MSDN wykonuje on zarówno dlaDispose(true)
iDispose(false)
, ale drugi występuje tylko wtedy, gdy obiekt jest sfinalizowany i tak czy inaczej zostanie zebrany śmieci!
Zatem moja preferencja będzie umieścić _resource = null
wewnątrz najbardziej wewnętrznej bloku if
:
if (disposing) {
if (_resource != null) {
_resource.Dispose();
_resource = null;
}
}
Utrzymuje cały kod _resource
razem. Dalsze myśli, ktoś?
Więcej czytanie:
- In the Dispose(bool) method implementation, Shouldn't one set members to null?
- Do you need to dispose of objects and set them to null?
- http://www.codeproject.com/KB/dotnet/idisposable.aspx (bardzo dobre, i długo!)
Służy ona większego sensu, ale ma trochę szkoda ... Właściwie, to byłoby bardziej zirytowany przez: pisanie na 'Console', a B: pisanie na' Console' nawet jeśli jest już usunięte, a my nie zrobił nie wyrzucaj go (patrz brak nawiasów klamrowych na "jeśli"). –
Haha! 'Console.Writeline()' jest przykładowym kodem. Czy Trace.Writeline() byłaby lepsza? Nie brakuje również klamry - jest na końcu linii 'if' (nie jest zgodna z StyleCop). –
jeszcze raz; pisze "Obiekt unieszkodliwiony". nawet jeśli '_resource' ma wartość zerową i dlatego nie wywołało' .Dispose() '. Mam na myśli najbardziej wewnętrzną * "jeśli". –