Шаблон Dispose в C#: реализация Dispose и GC.SuppressFinalizeC#

Место общения программистов C#
Ответить
Anonymous
 Шаблон Dispose в C#: реализация Dispose и GC.SuppressFinalize

Сообщение Anonymous »

Я изучаю шаблон Dispose в C# и понимаю, что метод Dispose используется при наличии неуправляемых ресурсов. Например, если у меня есть неуправляемый ресурс в FirstClass, а FirstClass содержится в классе Node, мне нужно реализовать метод Dispose для обоих, верно?
Чего я не понимаю самое главное, нужно ли мне вызывать GC.SuppressFinalize(this); в каждом методе Dispose.
GC.SuppressFinalize(this); указывает сборщику мусора не завершать работу, но означает ли это, что GC.SuppressFinalize(this); необходимо только в методе Dispose, если у класса есть финализатор? Если это так, я думаю, что это понадобится как в классе Node, так и в BaseClass. Однако, поскольку класс Node также имеет управляемые члены, допустимо ли в этом случае подавить финализатор?
Я в замешательстве, потому что существуют вложенные классы с методами Dispose. public class Node : IDisposable
{
public Node Next { get; set; } = null;
public Node Child { get; set; } = null;

public FirstClass CppInstance { get; set; } = null;

public Node()
{
CppInstance = new FirstClass();
}

~Node()
{
this.Dispose();
}

public void Dispose()
{
this.CppInstance?.Dispose();
}
}

public class FirstClass : BaseClass
{
private List _nameList = [];

public FirstClass()
{
CreateCppData( out _instance );// C++ Function create
_nameList.Add("A");
_nameList.Add("B");
_nameList.Add("C");
}

protected override void Dispose( Boolean disposing )
{
if( !disposedValue )
{
if( disposing )
{
// Managed resource release
_nameList.Clear();
_nameList = null;
}

// Unmanaged resource release
DeleteCppData( ref _instance ); // C++ Function delete
disposedValue = true;
}
}

}

public class BaseClass :IDisposable
{
protected Boolean disposedValue = false;

protected IntPtr _instance; // ● Unmanaged Data

~BaseClass()
{
Dispose( false );
}

protected virtual void Dispose( Boolean disposing )
{
}

public void Dispose()
{
this.Dispose( disposing: true );
GC.SuppressFinalize( this );
}

public virtual void Run()
{
}
}


C# переписал по совету.
public class Node : IDisposable
{
public Node Next { get; set; } = null;
public Node Child { get; set; } = null;

public FirstClass FirstClassInstance { get; set; } = null;
protected Boolean disposedValue = false;

public Node()
{
FirstClassInstance = new FirstClass();
}

~Node()
{
this.Dispose( false );
}

public void Dispose()
{
this.Dispose( true );
GC.SuppressFinalize( this );
}

protected virtual void Dispose( Boolean disposing )
{
if( !disposedValue )
{
this.FirstClassInstance?.Dispose();
this.FirstClassInstance = null;
disposedValue = true;
}
}
}

public class FirstClass : BaseClass
{
private List _nameList = [];

public FirstClass()
{
_nameList.Add("A");
_nameList.Add("B");
_nameList.Add("C");
}

protected override void Dispose( Boolean disposing )
{
if( !disposedValue )
{
if( disposing )
{
// Managed resource release
_nameList.Clear();
_nameList = null;
}

base.Dispose( disposing ); // BaseClass Dispose
}
}

protected override void CreateCppInstance()
{
CreateCppData( out _instance ); // C++ Function create
}

protected override void DeleteCppInstance()
{
DeleteCppData( ref _instance ); // C++ Function delete
}
}

public class BaseClass :IDisposable
{
protected Boolean disposedValue = false;

protected IntPtr _instance; // ● Unmanaged Data

public BaseClass()
{
CreateCppInstance();
}

~BaseClass()
{
Dispose( false );
}

protected virtual void CreateCppInstance()
{
throw new Exception();
}

protected virtual void DeleteCppInstance()
{
throw new Exception();
}

protected override void Dispose( Boolean disposing )
{
if( !disposedValue )
{
if( disposing )
{
// Managed resource release
}
// Unmanaged resource release
DeleteCppInstance();
disposedValue = true;
}
}

public void Dispose()
{
this.Dispose( disposing: true );
GC.SuppressFinalize( this );
}
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... ssfinalize
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»