2010-06-11 14 views
8

W moich metodach Dispose (jak ten poniżej), za każdym razem, gdy chcę wywołać someObj.Dispose(), mam również check dla someObj! = Null.Pozbywanie się członków implementujących IDisposable

Czy to z powodu złego projektu z mojej strony? Czy ich metoda jest czystsza, aby stwierdzić, że wszystkie elementy członkowskie (implementujące IDisposable) używane w obiekcie są wywoływane bez ryzyka wyjątku NullReference?

protected void Dispose(bool disposing) 
     { 
      if (disposing) 
      { 
       if (_splitTradePopupManager != null) 
       { 
        _splitTradePopupManager.Dispose(); 
       } 
      } 
     } 

Dzięki za zainteresowanie.

Odpowiedz

4

Może ktoś inny może zabrzmieć w tej sprawie, ale osobiście nie uważam, że jest to wada projektowa - tylko najbezpieczniejszy sposób na to.

Powiedział, że nic nie powstrzymuje cię od owijania czek null i Dispose połączenia w wygodny sposób:

private void DisposeMember(IDisposable member) 
{ 
    if (member != null) 
     member.Dispose(); 
} 

Następnie metoda Dispose mógłby wyglądać czystsze bitowe:

protected void Dispose(bool disposing) 
{ 
    if (disposing) 
    { 
     DisposeMember(_splitTradePopupManager); 
     DisposeMember(_disposableMember2); 
     DisposeMember(_disposableMember3); 
    } 
} 

jako dodatkowy bonus, to również rozwiązuje potencjalne warunki wyścigu w oryginalnym kodzie. W przypadku uruchamiania w kontekście wielowątkowym, wzorzec if (_field != null) _field.Dispose() może spowodować ustawienie NullReferenceException, gdy zostanie ustawione na wartość pomiędzy sprawdzeniem a usunięciem (rzadkie, ale możliwe). Przekazanie _field jako argumentu dla metody, takiej jak DisposeMember, powoduje skopiowanie odwołania do zmiennej lokalnej w metodzie, eliminując tę ​​możliwość, co jest mało prawdopodobne.

+1

Uzgodniono, że nie jest to błąd konstrukcyjny. Być może jestem zbyt ostrożny, ale wolę mieć kontrolę zerową, nawet jeśli wiem, że obiekt nigdy nie będzie miał wartości zerowej, jeśli chodzi o materiały jednorazowe. –

+0

@ ccomet: +1, mam takie samo myślenie (nadmiernie ostrożne) w czasie, gdy wywołuję Dispose() na obiekcie. –

0

Tylko ty znasz odpowiedź na to!

Nie widząc całej klasy trudno jest komukolwiek powiedzieć, czy możliwe jest, że członkowie ci kiedykolwiek będą nieważni, gdy zostanie wywołana Dispose.

(Oczywiście, z reguły jest to zawsze możliwe, że typ odniesienia lub typ wartości pustych być null, więc to chyba dobra praktyka, aby zawsze zawierać te zerowe kontrole w każdym razie).

0

Jedyną inną opcją, o której mógłbym pomyśleć, to stworzenie pomocniczej metody DisposeParameter, która ma obiekt będący jego parametrem i sprawdza tylko, czy jest to wartość NULL i w inny sposób Pozbyć się jej. W ten sposób potrzebujesz tylko jednego wiersza kodu, aby go usunąć, ale nie jestem pewien, czy to sprawi, że będzie on bardziej czytelny.

-1

Spróbuj tego.

protected void Dispose(bool disposing) 
    { 
     if (disposing) 
     { 
      //for all members.. 
      if (null != member && member is IDisposible) 
      { 
       member.Dispose(); 
      } 
     } 
    } 
+0

Nie jestem pewien, czy rozumiem, co sugerujesz tutaj. –

+0

Czy ktoś może uzasadnić głosowanie negatywne? –

+4

To nie byłem ja, ale sprawdzenie, czy element jest "IDisposable" jest trochę głupie, ponieważ wywołanie 'member.Dispose()' nie skompilowałoby się, gdy 'member' nie byłby typem jednorazowego użytku. – Steven

9

Lubię rozwiązanie @Dan Tao, ale jest dużo lepiej jako metodę rozszerzenia, imo:

public static void SafeDispose(this IDisposable obj) 
{ 
    if (obj != null) 
     obj.Dispose(); 
} 

Teraz można po prostu zadzwonić member.SafeDispose() na dowolnym IDisposable w programie bez obaw. :)

+0

To przyniesie wyjątek odwołania zerowy, gdy próbuje wywołać metodę rozszerzenia? Edycja - napisałem szybką aplikację testową i działa świetnie! –

+0

Nie, nie będzie. Użyłem podobnego podejścia w projekcie (DisposeIfNotNull()). –

+2

Nie! Ponieważ operator kropki jest po prostu cukrem syntaktycznym dla metody statycznej, działa dobrze. :) – tzaman

Powiązane problemy