Я изучаю шаблон 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
Шаблон Dispose в C#: реализация Dispose и GC.SuppressFinalize ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение