ReflectionIT.DisposeGenerator
0.1.0-preview
Prefix Reserved
See the version list below for details.
dotnet add package ReflectionIT.DisposeGenerator --version 0.1.0-preview
NuGet\Install-Package ReflectionIT.DisposeGenerator -Version 0.1.0-preview
<PackageReference Include="ReflectionIT.DisposeGenerator" Version="0.1.0-preview" />
<PackageVersion Include="ReflectionIT.DisposeGenerator" Version="0.1.0-preview" />
<PackageReference Include="ReflectionIT.DisposeGenerator" />
paket add ReflectionIT.DisposeGenerator --version 0.1.0-preview
#r "nuget: ReflectionIT.DisposeGenerator, 0.1.0-preview"
#:package ReflectionIT.DisposeGenerator@0.1.0-preview
#addin nuget:?package=ReflectionIT.DisposeGenerator&version=0.1.0-preview&prerelease
#tool nuget:?package=ReflectionIT.DisposeGenerator&version=0.1.0-preview&prerelease
ReflectionIT.DisposeGenerator
A source generator package that implements the Dispose pattern.
- https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern
- https://docs.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-dispose
Planned future support includes the async dispose pattern and unmanaged resources.
https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/implementing-disposeasync
NuGet package
| Package | Version |
|---|---|
| ReflectionIT.DisposeGenerator |
Example
Install the NuGet package, then annotate a class or struct with the Disposable attribute.
Annotate properties or fields with the Dispose attribute. Use the SetToNull when the property or field holds a large object and should be set to null after disposal.
using ReflectionIT.DisposeGenerator.Attributes;
[Disposable]
public partial class LogWriter : IDisposable {
[Dispose(SetToNull = true)]
private StreamWriter StreamWriter { get; set; }
public LogWriter(string path) => StreamWriter = new StreamWriter(path);
public void WriteLine(string text) => StreamWriter.WriteLine($"{DateTime.Now}\t{text}");
}
This generates the following partial class, which disposes the StreamWriter property and sets it to null.
partial class LogWriter
{
public void Dispose() {
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
global::System.GC.SuppressFinalize(this);
}
private bool _isDisposed;
protected virtual void Dispose(bool disposing) {
if (!_isDisposed) {
if (disposing) {
StreamWriter?.Dispose();
}
StreamWriter = null;
_isDisposed = true;
}
}
}
Implement the dispose pattern for a derived class
A class derived from a class that already implements IDisposable should not implement IDisposable again, because the base class implementation of IDisposable.Dispose is inherited by derived classes.
Set the OverrideDispose property of the Disposable attribute to true. In that case, the public parameterless Dispose method is not generated, and the protected Dispose(bool) method is generated as an override.
[Disposable(OverrideDispose = true)]
public partial class SecondLogWriter : LogWriter {
[Dispose]
private StreamWriter SecondStreamWriter { get; }
public SecondLogWriter(string path) : base(path) => SecondStreamWriter = new StreamWriter(path + "2");
public override void WriteLine(string text) {
base.WriteLine(text);
SecondStreamWriter.WriteLine($"{DateTime.Now}\t{text.ToUpper()}");
}
}
This generates the following partial class, which disposes the SecondStreamWriter property.
partial class SecondLogWriter
{
private bool _isDisposed;
protected override void Dispose(bool disposing) {
if (!_isDisposed) {
if (disposing) {
SecondStreamWriter?.Dispose();
}
_isDisposed = true;
}
base.Dispose(disposing);
}
}
Thread-safe disposal
Use Interlocked.CompareExchange to ensure thread-safe disposal. Set the IsThreadSafe property of the Disposable attribute to true.
[Disposable(IsThreadSafe = true)]
public partial class LogWriter : IDisposable {
[Dispose]
private readonly StreamWriter _streamWriter;
public LogWriter(string path) => _streamWriter = new StreamWriter(path);
public void WriteLine(string text) => _streamWriter.WriteLine($"{DateTime.Now}\t{text}");
}
This generates the following partial class, which uses Interlocked.CompareExchange to ensure thread-safe disposal.
partial class LogWriter
{
public void Dispose() {
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
global::System.GC.SuppressFinalize(this);
}
private int _isDisposed;
protected virtual void Dispose(bool disposing) {
if (global::System.Threading.Interlocked.CompareExchange(ref _isDisposed, 1, 0) == 0) {
if (disposing) {
_streamWriter?.Dispose();
}
}
}
}
License
This project is licensed under the MIT License - see the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.4.1-preview | 49 | 6/4/2026 |
| 0.4.0-preview | 59 | 4/29/2026 |
| 0.3.0-preview | 55 | 4/28/2026 |
| 0.2.0-preview | 59 | 4/20/2026 |
| 0.1.0-preview | 53 | 4/20/2026 |