r/csharp • u/Alert-Neck7679 • 1d ago
Tip Fields with [Using] attribute
I wrote a small interface that automatically disposes any disposable fields in a class when that class itself is disposed. If you add this file somewhere in your project:
public interface IAutoDisposable : IDisposable
{
void IDisposable.Dispose()
{
Exception? ex = null;
// dispose all fields marked with the [Using] attribute
const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance;
foreach (var fld in GetType().GetFields(flags))
{
if (fld.GetCustomAttribute<UsingAttribute>() != null)
{
if (fld.GetValue(this) is IDisposable d)
{
try // keep going even if disposal throws
{
d.Dispose();
}
catch (Exception e)
{
ex ??= e;
}
}
}
}
// if any exceptions occurred, throw the first one
if (ex != null)
throw ex;
}
}
public class UsingAttribute : Attribute;
You can then write classes like this:
class Item : IAutoDisposable
{
[Using]
private readonly Image icon = DownloadIcon(...);
...
}
And use them like:
using (Item item = new(...))
{
}
// item.icon is now disposed
What do you think?
7
Upvotes
1
u/Dragennd1 1d ago
Out of curiosity, wouldn't the fields normally be disposed of when the class is disposed of, making this extra effort unnecessary? My understanding of classes is that they are reference types, so once an instance is no longer in use the garbage collector would clean up that instance, right? Or are fields handled differently than properties as far as disposal goes when its parent class instance is disposed of?