SqlCommand cmd = new SqlCommand();
        cmd.Dispose();
        System.GC.Collect();
        cmd.CommandText = "";
        cmd.Dispose();

can please explain why this code is not showing error.......

That is a very interesting find..... and I cannot explain why it is isn't throwing the object disposed exception. It seems SqlCommand doesn't implement IDisposable but DBCommand does, and SqlCommand overrides the base Dispose() method. It looks like a bug in the CLR.

You can see where it is overriden in SqlCommand:

protected override void Dispose(bool disposing);

That is very odd....I tried to use reflection to get the object disposed exception but no luck:

{
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = "abc123";

        BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.InvokeMethod;
        MethodInfo mi = typeof(SqlCommand).GetMethod("Dispose", bf);
        mi.Invoke(cmd, new object[] { true });
        mi.Invoke(cmd, new object[] { false });
        cmd.CommandText = "123123";
        Debugger.Break();
      }

      {
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = "abc123";
        BindingFlags bf = BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public;
        MethodInfo mi = typeof(Component).GetMethod("Dispose", bf);
        mi.Invoke(cmd, null);
        cmd.CommandText = "123123";
      }

SqlCommand inherits from DBCommand

Which is why I was pointing that out... You can only override if you inherit the method.

Comments
Nice remark!

Yes I say it inherits from DBCommand and overrides Dispose method

Comments
I meant to thank you for posting about .net decompilers
Attachments sql_command_dispose_method.jpg 75.2 KB

I guess I have made it this far in my life without thoroughly testing disposed objects but it is up to the implemented class to throw the ObjectDisposedException. I have seen this exception with various System.Windows.Form.Control but I haven't tested it against classes where IDisposable was implemented. In this case they just didn't throw the exceptions..

Read this article:
http://stackoverflow.com/questions/668440/handling-objectdisposedexception-correctly-in-an-idisposable-class-hierarchy

You learn something new every day on DaniWeb :)

SqlCommand inherits from DBCommand which inherits from Component
Component has this implmenetation of Dispose

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        lock (this)
        {
            if ((this.site != null) && (this.site.Container != null))
            {
                this.site.Container.Remove(this);
            }
            if (this.events != null)
            {
                EventHandler handler = (EventHandler) this.events[EventDisposed];
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            }
        }
    }
}

I couldn't figure out those lines and I have to catch every line and know where and what to call, so I added that to my to do list :)

I knew it I knew it, YOU CAN'T call disposed explicit in your code, because to dispose the component your should by pass bool to true and the dispose method which has parameter (bool) is protected which means SqlCommand itself in specific time call it.

thanks for all,
still i didn't get clarification.

SqlCommand cmd = new SqlCommand();
        cmd.Dispose();
        System.GC.Collect();
        cmd.CommandText = "";

in the above code last line should throw that object is not valid(since it was disposed)....but it didn't...
but i got the exception when i use like this.

SqlCommand cmd = new SqlCommand();
        //cmd.Dispose();
        //System.GC.Collect();
cmd=Null;
        cmd.CommandText = "";

Who said it being disposed?! (we've clarified above) cmd=Null; you made it refers to null which gets exception Object reference not set to an instance of an object.

It may have been disposed but it is up to the implementation of the class to throw the ObjectDisposed exception and in this case SqlCommand does not have that behavior.

Hi,

When you do:

cmd.Dispose();

you are not really dispose the object the minute that you do it,
its only tells to the Garbage Collection that you dont need this object any more, and sugesting him to dispose the object, you cant force the Garbage Collection to dispose the object, its doing it when "he thinks" that its ready to dispose the object.
Its not like in c++ that you could dispose the object manually when ever that you wanted!
See the following link to read about the Garbage Collection:
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx


As for "null" you dont either dispose the object, the only thing that you do is lossing the reffernce to the object in memory.

Hi,

When you do:

cmd.Dispose();

you are not really dispose the object the minute that you do it,
its only tells to the Garbage Collection that you dont need this object any more, and sugesting him to dispose the object, you cant force the Garbage Collection to dispose the object, its doing it when "he thinks" that its ready to dispose the object.
Its not like in c++ that you could dispose the object manually when ever that you wanted!
See the following link to read about the Garbage Collection:
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx


As for "null" you dont either dispose the object, the only thing that you do is lossing the reffernce to the object in memory.

You can force the garbage collector to run:
http://msdn.microsoft.com/en-us/library/s5zscb2d(VS.85).aspx

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

I tested calling the collector to get the ObjectDisposed implementation but as Ramy posted code for -- the class doesn't throw the exception.

You can force the garbage collector to run:
http://msdn.microsoft.com/en-us/library/s5zscb2d(VS.85).aspx

GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

I tested calling the collector to get the ObjectDisposed implementation but as Ramy posted code for -- the class doesn't throw the exception.

Hi sknake,
thank you for you answer as i learned somthing new here, i really had no idea that you can call GC.Collect();
At first i thought that even if you call it its only a suggestion for the GC to run and it does not have to run, but after i read the link, and read a bunch of threads on the web i realized that you are right and you can call the GC.Collect(), and it will dispose everthing that you dont want.
But there is a lot of threads out there that really suggest not to call to GC.Collect() and let the GC to run independenty as it can do more problem then it can help you!

This article has been dead for over six months. Start a new discussion instead.