Как определить, расположена ли ссылка на объект IDisposable?

Есть ли метод или какой-то другой легкий способ проверить, является ли ссылка на удаленный объект?

P.S. - Это просто любопытство (спи спокойно, а не в производственном коде). Да, я знаю, что могу поймать ObjectDisposedException при попытке доступа к члену объекта.

75 голосов | спросил Neil C. Obremski 10 +04002008-10-10T20:44:05+04:00312008bEurope/MoscowFri, 10 Oct 2008 20:44:05 +0400 2008, 20:44:05

8 ответов


0

Зависит от того, что есть IDisposable объекты, которые позволяют вызывать Dispose столько, сколько вы хотите, и есть IDisposable объекты, которые выбрасывают ObjectDisposedException. В таком случае эти объекты должны отслеживать состояние (обычно реализуемое с помощью частного логического поля isDisposed).

ответил Michael Damatov 10 +04002008-10-10T20:51:19+04:00312008bEurope/MoscowFri, 10 Oct 2008 20:51:19 +0400 2008, 20:51:19
0

Нет - реализация шаблона IDisposable по умолчанию не поддерживает его

ответил Dandikas 10 +04002008-10-10T20:48:16+04:00312008bEurope/MoscowFri, 10 Oct 2008 20:48:16 +0400 2008, 20:48:16
0

System.Windows.Forms.Control имеет IsDisposed свойство, которое является устанавливается в значение true после Dispose() называется . В ваших собственных объектах IDisposable вы можете легко создать подобное свойство.

ответил Ryan Lundy 10 +04002008-10-10T20:49:02+04:00312008bEurope/MoscowFri, 10 Oct 2008 20:49:02 +0400 2008, 20:49:02
0

Там нет ничего встроенного, что позволило бы это. Вам нужно будет предоставить логическое свойство IsDisposed, которое отражает внутренний флаг удаления.

public class SimpleCleanup : IDisposable
{
    private bool disposed = false;

    public bool IsDisposed
    {
       get
       {
          return disposed;
       }
    }

    public SimpleCleanup()
    {
        this.handle = /*...*/;
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
               // free only managed resources here
            }

            // free unmanaged resources here
            disposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
    }
}
ответил Scott Dorman 17 +04002008-10-17T12:49:49+04:00312008bEurope/MoscowFri, 17 Oct 2008 12:49:49 +0400 2008, 12:49:49
0

Если это не ваш класс и он не предоставляет свойство IsDisposed (или что-то подобное - это просто соглашение), то у вас нет возможности узнать.

Но если это ваш класс, и вы следуете канонической реализации IDisposable , затем просто откройте поле _disposed или _isDisposed как свойство и проверьте это.

ответил jop 10 +04002008-10-10T20:56:22+04:00312008bEurope/MoscowFri, 10 Oct 2008 20:56:22 +0400 2008, 20:56:22
0

Метод Dispose необходим для выполнения любой очистки перед тем, как покинуть объект; если очистка не требуется, ничего делать не требуется. Требование к объекту отслеживать, был ли он удален, даже если в противном случае метод Dispose ничего не будет делать, потребуется много IDisposable объекты для добавления флага для очень ограниченной выгоды.

Возможно, было бы полезно, если бы IDisposable включало два свойства - одно из которых указывало, нужно ли объекту удалять и один из них указывает на то, что объект не был сделан бесполезным путем утилизации. Для объектов, где удаление действительно что-то делает, оба значения будут изначально истинными и станут ложными после Dispose. Для объектов, для которых удаление не требует какой-либо очистки, первый метод всегда может возвращать false, а второй всегда true, без необходимости хранить флаг где-либо. Однако я не думаю, что они могут быть добавлены в .NET сейчас.

ответил supercat 8 +03002015-10-08T19:37:59+03:00312015bEurope/MoscowThu, 08 Oct 2015 19:37:59 +0300 2015, 19:37:59
0

Я вижу, что это старый, но я не видел ответа. Некоторые не все одноразовые объекты, такие как DataSet, имеют событие удаления, которое вы можете прикрепить.

class DisposeSample : IDisposable
{
    DataSet myDataSet = new DataSet();
    private bool _isDisposed;

    public DisposeSample()
    {
        // attach dispose event for myDataSet
        myDataSet.Disposed += MyDataSet_Disposed;
    }

    private void MyDataSet_Disposed(object sender, EventArgs e)
    {
        //Event triggers when myDataSet is disposed
        _isDisposed = true; // set private bool variable as true 
    }


    public void Dispose()
    {
        if (!_isDisposed) // only dispose if has not been disposed;
            myDataSet?.Dispose(); // only dispose if myDataSet is not null;
    }
}
ответил Moses 14 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 14 Sep 2018 03:56:54 +0300 2018, 03:56:54
0

Что мне нравится делать, так это объявлять объекты без их инициализации, но устанавливать для их значений по умолчанию значение Nothing. Затем в конце цикла я пишу:

 If anObject IsNot Nothing Then anObject.Dispose()

Вот полный пример:

 Public Sub Example()
    Dim inputPdf As PdfReader = Nothing, inputDoc As Document = Nothing, outputWriter As PdfWriter = Nothing

    'code goes here that may or may not end up using all three objects, 
    ' such as when I see that there aren't enough pages in the pdf once I open  
    ' the pdfreader and then abort by jumping to my cleanup routine using a goto ..

GoodExit:
    If inputPdf IsNot Nothing Then inputPdf.Dispose()
    If inputDoc IsNot Nothing Then inputDoc.Dispose()
    If outputWriter IsNot Nothing Then outputWriter.Dispose()
End Sub

Это также отлично подходит для размещения ваших главных объектов в верхней части подпрограммы, использования их внутри подпрограммы Try, а затем удаления их в блоке Finally:

 Private Sub Test()
    Dim aForm As System.Windows.Forms.Form = Nothing
    Try
        Dim sName As String = aForm.Name  'null ref should occur
    Catch ex As Exception
        'got null exception, no doubt
    Finally
        'proper disposal occurs, error or no error, initialized or not..
        If aForm IsNot Nothing Then aForm.Dispose()
    End Try
End Sub
ответил JeffreyDurham 8 SunEurope/Moscow2013-12-08T00:43:56+04:00Europe/Moscow12bEurope/MoscowSun, 08 Dec 2013 00:43:56 +0400 2013, 00:43:56

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132