Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 350723
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T11:34:36+00:00 2026-05-12T11:34:36+00:00

I am not a fan of boilerplate code: copy-paste reuse is potentially error-prone. Even

  • 0

I am not a fan of boilerplate code: copy-paste reuse is potentially error-prone. Even if you use code snippets or smart templates, there is no guarantee the other developer did, which means there’s no guarantee they did it right. And, if you have to see the code, you have to understand it and/or maintain it.

What I want to know from the community is: is my implementation of IDispose for a class hierarchy a legitimate alternative to the “traditional” dispose pattern? By legitimate, I mean correct, reasonably well performing, robust, and maintainable.

I am ok with this alternative being plain wrong, but if it is, I’d like to know why.

This implementation assumes you have full control over the class hierarchy; if you don’t you’ll probably have to resort back to boilerplate code. The calls to Add*() would typically be made in the constructor.

public abstract class DisposableObject : IDisposable
{
  protected DisposableObject()
  {}

  protected DisposableObject(Action managedDisposer)
  {
     AddDisposers(managedDisposer, null);
  }

  protected DisposableObject(Action managedDisposer, Action unmanagedDisposer)
  {
     AddDisposers(managedDisposer, unmanagedDisposer);
  }

  public bool IsDisposed
  {
     get { return disposeIndex == -1; }
  }

  public void CheckDisposed()
  {
     if (IsDisposed)
        throw new ObjectDisposedException("This instance is disposed.");
  }

  protected void AddDisposers(Action managedDisposer, Action unmanagedDisposer)
  {
     managedDisposers.Add(managedDisposer);
     unmanagedDisposers.Add(unmanagedDisposer);
     disposeIndex++;
  }

  protected void AddManagedDisposer(Action managedDisposer)
  {
     AddDisposers(managedDisposer, null);
  }

  protected void AddUnmanagedDisposer(Action unmanagedDisposer)
  {
     AddDisposers(null, unmanagedDisposer);
  }

  public void Dispose()
  {
     if (disposeIndex != -1)
     {
        Dispose(true);
        GC.SuppressFinalize(this);
     }
  }

  ~DisposableObject()
  {
     if (disposeIndex != -1)
        Dispose(false);
  }

  private void Dispose(bool disposing)
  {
     for (; disposeIndex != -1; --disposeIndex)
     {
        if (disposing)
           if (managedDisposers[disposeIndex] != null)
              managedDisposers[disposeIndex]();
        if (unmanagedDisposers[disposeIndex] != null)
           unmanagedDisposers[disposeIndex]();
     }
  }

  private readonly IList<Action> managedDisposers = new List<Action>();
  private readonly IList<Action> unmanagedDisposers = new List<Action>();
  private int disposeIndex = -1;
}

This is a “complete” implementation in the sense I provide support for finalization (knowing most implementations don’t need a finalizer), checking whether an object is disposed, etc. A real implementation may remove the finalizer, for example, or create a subclass of DisposableObject that includes the finalizer. Basically, I threw in everything I could think of just for this question.

There are probably some edge cases and esoteric situations I’ve missed, so I invite anyone to poke holes in this approach or to shore it up with corrections.

Other alternatives might be to use a single Queue<Disposer> disposers in DisposableObject instead of two lists; in this case, as disposers are called, they are removed from the list. There are other slight variations I can think of, but they have the same general result: no boilerplate code.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T11:34:36+00:00Added an answer on May 12, 2026 at 11:34 am

    The first issue you will potentially hit is that C# only allows you to inherit from a single base class, which in this case will always be DisposableObject. Right here you have cluttered your class hierarchy by forcing additional layers so that classes that need to inherit from DisposableObject and some other object can do so.

    You are also introducing a lot of overhead and maintenance issues down the road with this implementation (not to mention the repeated training costs everytime someone new comes on to the project and you have to explain how they should use this implementation rather than the defined pattern). You know have multiple states to keep track of with your two lists, there is no error handling around the calls to the actions, the syntax when calling an action looks “wierd” (while it may be common to invoke a method from an array, the syntax of simply putting the () after the array access just looks strange).

    I understand the desire to reduce the amount of boilerplate you have to write, but disposability is generally not one of those areas that I would recommend taking short-cuts or otherwise deviating from the pattern. The closest I usually get is to use a helper method (or an extension method) that wraps the actual call to Dispose() on a given object. These calls typically look like:

    if (someObject != null)
    {
       someObject.Dispose();
    }
    

    This can be simplified using a helper method, but keep in mind that FxCop (or any other static analysis tool that checks for correct dispose implementations) will complain.

    As far as performance is concerned, keep in mind that you are making a lot of delegate calls with this type of implementation. This is, by nature of a delegate, somewhat more costly than a normal method call.

    Maintainability is definately an issue here. As I mentioned, you have the repeated training costs everytime someone new comes on to the project and you have to explain how they should use this implementation rather than the defined pattern. Not only that, you have problems with everyone remembering to add their disposable objects to your lists.

    Overall, I think doing this is a bad idea that will cause a lot of problems down the road, especially as the project and team size increase.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm not a fan of PHP or spaghetti code, or anything like that, but
I'm not a fan of the whole 'portal dockbar' for normal users (we use
I'm not a fan of statics but I've got some code that has: The
Because I'm a programmer who likes clear, concise and less error-prone code, I always
I am not a fan of the following construction if (self = [super init])
I'm generally not a fan of microbenchmarks. But this one has a very interesting
I'm not a fan of using ASP.NET session state, but our application is using
I'm looking for something current, iOS5 and Xcode 4.2. I'm not a fan of
I'm not yet a fan of integrated development environments, but I'm trying to overcome
I'm not a big fan of XML files. Therefore I'm wondering if there is

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.