tags:

views:

67

answers:

3

Here is what I have:

public void FindByID(string id)
{
    using (Parser parser = new Parser()) {
        if ( parser.LoadUserById(id)) {
            ID = parser.FindID();
            Name = parser.FindName();
            // ...
        }
        else {
            MessageBox.Show("User not found.");
        }
    } // end using block. parser is disposed so its memory is free to use again. 
}

And here is the actual Parser class itself:

public class Parser : IDisposable
    {                
        XDocument doc;
        bool userExists = true;
        private const string xmlInformationAddress = "http://www.dreamincode.net/forums/xml.php?showuser={0}";

        public bool LoadUserById(string userID)
        {
            try
            {
                doc = XDocument.Load(String.Format(xmlInformationAddress, userID));

                if (doc.Root.Elements().Any())
                {
                    userExists = true;
                    return true;
                }
                else 
                {
                    userExists = false;                
                    return false;
                }
            }
            catch (Exception e)
            {
                doc = new XDocument();
                userExists = false;
                return false;
            }               


        }
     }

It says I'm not implementing the Dispose() method, but I'm not sure what is supposed to go inside of that method.

+10  A: 

Well, why do you want to implement IDisposable? If you've got nothing to dispose of (which looks like it's the case here) then clients shouldn't have to call Dispose.

You seem to be under the impression that calling Dispose will free the memory taken by the object. That's the garbage collector's job - Dipose is entirely separate. It's designed to release unmanaged resources such as file handles (including those indirectly held, such as references to Streams).

In this case:

  • Don't implement IDisposable
  • Get rid of the using statement in your calling code
  • Trust the GC :)
Jon Skeet
I'm under the impression that after the Parser class loads all relevant information to my visual controls, the Using will do it's thing and dispose the parser Object, right?
Sergio Tapia
@sergio: No. I edited my answer to give more details - but "Dispose" doesn't do anything with the memory - that's a matter of the GC.
Reed Copsey
@sergio: I have [three easy rules](http://nitoprograms.blogspot.com/2009/08/how-to-implement-idisposable-and.html) on my blog; this one falls under the first rule: "Don't do it."
Stephen Cleary
@Sergio: The using statement would indeed call `Dispose`... but there's nothing obvious that the parser should *do* when it's disposed. Why would you *want* to call `Dispose`?
Jon Skeet
+3  A: 

Your class doesn't seem like it needs to implement IDisposable. That being said, if you want to understand how and why you would implement it, you could read my series on IDisposable. It goes into how and why (and when) you should implement IDisposable in detail.

In this case, you have no reason to use IDisposable, since your object doesn't hold any native resources. If it used native resources, or encapsulated another class that implemented IDisposable, then, and only then, you should implement IDisposable.

That being said, IDisposable has nothing to do with freeing memory - that's the job of the GC. It's about freeing resources, which can include memory (allocated natively), but more often involves native handles and other resources.

Reed Copsey
Very nice blog post. Good work
NickLarsen
Native resources aren't the only reason to implement iDisposable. Shouldn't objects which subscribe to any type of events from longer-lived objects, or otherwise inform longer-lived objects of their existence, also implement iDisposable, even if neither they, nor the objects to whose events they are subscribed, use native resources? To be sure, the present parser implementation doesn't seem to attach itself to longer-lived objects, but it's a common enough scenario that should be considered in deciding whether to make something disposable.
supercat
@supercat: I never specified the resources must be native. There are other valid reasons, such as factored types: http://reedcopsey.com/2009/04/25/idisposable-part-4-factored-types/
Reed Copsey
A: 

I agree with Jon Skeet. But if you did have something to "dispose" of -

var x = new Parser();
using (x) {
   // Do stuff
}
Kris Krause
That's not really what he's asking... he's writing the Parser class himself and wondering how to implement the IDisposable interface within the class itself.But I agree it's unnecessary here.
Tim Goodman
Also, there is no advantage to this over the way the OP wrote it. Putting the new Parser line into the using statement is fine...
Reed Copsey
Indeed, putting the declaration of the parser variable into the using statement is *preferable* as then it doesn't stay in scope after the object has been disposed.
Jon Skeet