Coplt.Dropping
July 8, 2026 ยท View on GitHub
Auto gen dispose pattern
- Auto handle
Dispose(bool dispoing)pattern - Auto handle destructor/finalizer
- Allow multiple drops
- Specify the drop order
[Drop(Order = X)] - The first argument of
Droptarget method can bebool disposing - Mark Drop directly on fields and properties (requires target type have
Disposemethod) - Dose not supported
AsyncDispose, too complicated, it is recommended to implement it manually Dropcan mark on static methods, will passthison first argument, if havebool disposingwill be the second argument
Example
-
Basic usage
[Dropping] public partial class Foo1 { [Drop] public void Drop() { Console.WriteLine(1); } }Generate output:
Foo1.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial class Foo1 : global::System.IDisposable { protected virtual void Dispose(bool disposing) { Drop(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Foo1() { Dispose(false); } }
-
Drop Froms
[Dropping(From = DropFrom.Dispose)] public partial class Foo2 { [Drop] public void Drop() { Console.WriteLine(1); } } [Dropping(From = DropFrom.Finalizer)] public partial class Foo3 { [Drop] public void Drop() { Console.WriteLine(1); } }Generate output:
Foo2.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial class Foo2 : global::System.IDisposable { protected virtual void Dispose(bool disposing) { if (disposing) Drop(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Foo2() { Dispose(false); } }
Foo3.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial class Foo3 : global::System.IDisposable { protected virtual void Dispose(bool disposing) { if (!disposing) Drop(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Foo3() { Dispose(false); } }
-
Inherit
[Dropping] public partial class Foo8 : Foo1 { [Drop] public void Drop1() { Console.WriteLine(1); } }Generate output:
Foo8.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial class Foo8 : global::System.IDisposable { protected override void Dispose(bool disposing) { Drop1(); base.Dispose(disposing); } }
-
Sealed And Struct
[Dropping] public partial struct Foo7 { [Drop] private void Drop() { Console.WriteLine(1); } } [Dropping] public sealed partial class Foo9 { [Drop] private void Drop() { Console.WriteLine(1); } } [Dropping(From = DropFrom.Dispose)] public sealed partial class Foo10 { [Drop] private void Drop() { Console.WriteLine(1); } } [Dropping(From = DropFrom.Finalizer)] public sealed partial class Foo11 { [Drop] private void Drop() { Console.WriteLine(1); } }Generate output:
Foo7.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial struct Foo7 : global::System.IDisposable { public void Dispose() { Drop(); } }Foo9.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial class Foo9 : global::System.IDisposable { public void Dispose() { Drop(); GC.SuppressFinalize(this); } ~Foo9() { Dispose(); } }Foo10.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial class Foo10 : global::System.IDisposable { public void Dispose() { Drop(); } }Foo11.dropping.g.cs
// <auto-generated/> #nullable enable using Coplt.Dropping; public partial class Foo11 : global::System.IDisposable { private void Dispose(bool disposing) { if (!disposing) Drop(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~Foo11() { Dispose(false); } }
More see Tests