Udostępnij za pośrednictwem


CA2202: Nie należy usuwać obiektów wiele razy

Pozycja Wartość
Ruleid CA2202
Kategoria Microsoft.Usage
Zmiana powodująca niezgodność Niezgodność

Przyczyna

Implementacja metody zawiera ścieżki kodu, które mogą powodować wiele wywołań lub System.IDisposable.Dispose odpowiednik Dispose, taki jak metoda Close() w niektórych typach, na tym samym obiekcie.

Uwaga

Ta reguła została przestarzała. Aby uzyskać więcej informacji, zobacz Przestarzałe reguły.

Opis reguły

Poprawnie zaimplementowana Dispose metoda może być wywoływana wiele razy bez zgłaszania wyjątku. Nie jest to jednak gwarantowane i aby uniknąć generowania obiektu System.ObjectDisposedException , nie należy wywoływać Dispose więcej niż raz na obiekcie.

Jak naprawić naruszenia

Aby naprawić naruszenie tej reguły, zmień implementację tak, aby niezależnie od ścieżki kodu, Dispose było wywoływane tylko raz dla obiektu.

Kiedy pomijać ostrzeżenia

Nie pomijaj ostrzeżeń dla tej reguły. Nawet jeśli Dispose obiekt jest znany jako bezpieczny do wielokrotnego wywoływania, implementacja może ulec zmianie w przyszłości.

Przykład 1

Instrukcje zagnieżdżone using (Using w Visual Basic) mogą powodować naruszenia ostrzeżenia CA2202. Jeśli zasób IDisposable zagnieżdżonej instrukcji wewnętrznej using zawiera zasób instrukcji zewnętrznej using , Dispose metoda zagnieżdżonego zasobu zwalnia zawarty zasób. W takiej sytuacji Dispose metoda instrukcji zewnętrznej using próbuje usunąć zasób po raz drugi.

W poniższym przykładzie Stream obiekt utworzony w zewnętrznej instrukcji using jest zwalniany na końcu wewnętrznej instrukcji using w metodzie StreamWriter Dispose obiektu, który zawiera stream obiekt. Na końcu instrukcji stream zewnętrznej using obiekt jest zwalniany po raz drugi. Druga wersja jest naruszeniem ca2202.

using (Stream stream = new FileStream("file.txt", FileMode.OpenOrCreate))
{
    using (StreamWriter writer = new StreamWriter(stream))
    {
        // Use the writer object...
    }
}

Przykład 2

Aby rozwiązać ten problem, użyj try/finally bloku zamiast instrukcji zewnętrznej using . finally W bloku upewnij się, że stream zasób nie ma wartości null.

Stream stream = null;
try
{
    stream = new FileStream("file.txt", FileMode.OpenOrCreate);
    using (StreamWriter writer = new StreamWriter(stream))
    {
        stream = null;
        // Use the writer object...
    }
}
finally
{
    stream?.Dispose();
}

Napiwek

Powyższa składnia ?. jest operatorem warunkowym o wartości null.

Zobacz też