0

Can you please explain what is happening here?

using(DataSet ds = GetDataSet()) // will this get disposed? if yes (when?)
{
    using(DataTable dt = ds.Tables[0]) /* in this line is ds available for dt? i found some issue with this kind of statement. dt gets null after this line */
    {
          // i know that ds is available here.
          //some code
    }
}
MilkyWayJoe
  • 9,062
  • 2
  • 36
  • 53
Rakesh
  • 313
  • 4
  • 21
  • ds should be available for all lines of code up to the closing brace of the using if i'm not mistaken –  Apr 27 '12 at 20:27

6 Answers6

1
using(DataSet ds = GetDataSet()){

  using(DataTable dt = ds.Tables[0])
  // dt will be NULL if there are no tables in ds
  {
    // both dt & ds will be available here

  }// dt will get disposed

}// ds will be disposed at this point...

The equivalent code for this is:

try{
 DataSet ds = GetDataSet();
 try{
  DataTable dt = ds.Tables[0];
  // dt will not be null if there are any tables in ds
  // Both ds & dt available here...
 }
 finally{
  dt.Dispose();
 }
}
finally{
 ds.Dispose();
}
Sunny
  • 6,086
  • 2
  • 23
  • 26
1

Yes, ds will be disposed, at the last end bracket in your sample. Yes, ds is available when you're constructing dt. The reason dt is coming through as null must simply be that ds.Tables[0] is returning null. From the documentation, the null value means that the DataTable you're looking for doesn't exist. My guess is that the DataSet isn't being filled with values. See the documentation for an example.

Tim S.
  • 52,076
  • 7
  • 84
  • 114
0

The using() statement takes any IDisposable and will call Dispose() on it when it's scope is exited either via exception or normal execution.

Thus dt will be disposed first when it passes the inner closing }, and then ds will be disposed when the outer closing '}` is passed:

using(DataSet ds = GetDataSet()) 
{
    using(DataTable dt = ds.Tables[0]) 
    {
        ....
    } // <-- dt disposed here or if unhandled exception thrown

} // <-- ds disposed here or if unhandled exception thrown.

For more information, see the MSDN section on the Using statement

James Michael Hare
  • 35,710
  • 9
  • 67
  • 81
0

Yes, it will be disposed after you leave the from the corresponding bracket. Using calls dispose and it can only be used with objects that implement IDisposable.

Katu
  • 661
  • 1
  • 7
  • 22
0

The using statment here:

using (ResourceType resource = expression) { ... }

is equivalent to:

ResourceType resource = expression;
try {
    ...
}
finally {
   if (resource != null) ((IDisposable)resource).Dispose();
}

(if ResourceType is a value type, the null check will be omitted).

So in your case, the first using makes sense assuming GetDataSet() creates a new dataset that nobody else will be using later. The second using doesn't make much sense - you don't need to dispose of dataset tables, as far as I know.

The reason you're getting a null dt may be that there is nothing in the Tables collection.

sinelaw
  • 15,049
  • 2
  • 44
  • 78
0

think like this:

using resource

your resource will live here and will be available to all other children "using" statements or other methods

end of using

so to your questions:

ds will get disposed in the end of the first using block

dt will get the first DataTable found in ds and will be disposed in the end of its own using block

This happens because the using statement, in this form will always call the Dispose method of the resource it's managing, therefore, you can only use the using block for types that implement IDisposable

MilkyWayJoe
  • 9,062
  • 2
  • 36
  • 53