Question

Implement a simple C# class that uses the IDisposable interface for resource cleanup.

Answers

GPT-4o mini
Certainly! Below is an example of a simple C# class that implements the `IDisposable` interface. This class demonstrates proper resource management by implementing the necessary methods to release unmanaged resources.

### Example Class

```csharp
using System;

public class ResourceHolder : IDisposable
{
// Flag to indicate if the object has already been disposed
private bool disposed = false;

// Simulate an unmanaged resource
private IntPtr unmanagedResource;

public ResourceHolder()
{
// Allocate the unmanaged resource
unmanagedResource = /* allocate unmanaged resource */;
Console.WriteLine("Resource allocated.");
}

// Implementing the Dispose method
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

// Protected implementation of Dispose pattern
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// Dispose managed resources if any
// For example, if you had other disposable objects
// managedResource?.Dispose();
}

// Free unmanaged resources
if (unmanagedResource != IntPtr.Zero)
{
// Free the unmanaged resource here
Console.WriteLine("Unmanaged resource freed.");
unmanagedResource = IntPtr.Zero; // Example of cleaning up
}

disposed = true;
}
}

// Finalizer
~ResourceHolder()
{
Dispose(false);
}
}
```

### Key Components

1. **IDisposable Interface**: The class implements `IDisposable`, which provides the `Dispose` method for releasing resources.

2. **Dispose Pattern**: This pattern helps manage both managed and unmanaged resources gracefully.

- The `Dispose` method calls a protected `Dispose(bool disposing)` method, which determines whether to release managed resources (`disposing` is `true`) or only unmanaged resources (when called from the finalizer).
- The class has a finalizer (`~ResourceHolder()`) that calls `Dispose(false)` to clean up resources if `Dispose` was never called.

3. **Resource Cleanup**: The `Dispose(bool disposing)` method checks if the object has already been disposed of, and releases the necessary resources.

### Usage Example

Here’s how you would typically use the `ResourceHolder` class in a `using` statement or manually:

```csharp
class Program
{
static void Main()
{
using (ResourceHolder resourceHolder = new ResourceHolder())
{
// Use the resource
} // Automatic cleanup happens here

// Or without using statement
ResourceHolder resourceHolderManual = new ResourceHolder();
try
{
// Use the resource
}
finally
{
resourceHolderManual.Dispose(); // Manually clean up
}
}
}
```

The `using` statement ensures that `Dispose` is called automatically at the end of the block, while in the second usage, it is manually called in a `finally` block to guarantee cleanup even if an exception occurs.

Related Questions