Consider the following code snippet:
using System;
class Resource : IDisposable {
public void Dispose() {
Console.WriteLine("Resource disposed");
}
public void Use() {
Console.WriteLine("Resource in use");
}
}
class Program {
static void Main() {
using (var r = new Resource()) {
r.Use();
}
Console.WriteLine("End of Main");
}
}What will be printed when this program runs?
using System; class Resource : IDisposable { public void Dispose() { Console.WriteLine("Resource disposed"); } public void Use() { Console.WriteLine("Resource in use"); } } class Program { static void Main() { using (var r = new Resource()) { r.Use(); } Console.WriteLine("End of Main"); } }
Think about when the Dispose method is called in a 'using' block.
The 'using' statement ensures Dispose is called immediately after the block finishes. So first 'Resource in use' prints, then 'Resource disposed', then 'End of Main'.
Look at this code:
using System;
class Resource : IDisposable {
public void Dispose() {
Console.WriteLine("Disposed");
}
public void Use() {
Console.WriteLine("Using resource");
throw new Exception("Error");
}
}
class Program {
static void Main() {
try {
using (var r = new Resource()) {
r.Use();
}
} catch (Exception e) {
Console.WriteLine(e.Message);
}
}
}What will be the output when this runs?
using System; class Resource : IDisposable { public void Dispose() { Console.WriteLine("Disposed"); } public void Use() { Console.WriteLine("Using resource"); throw new Exception("Error"); } } class Program { static void Main() { try { using (var r = new Resource()) { r.Use(); } } catch (Exception e) { Console.WriteLine(e.Message); } } }
Dispose is called even if an exception happens inside the 'using' block.
The 'using' statement calls Dispose in a finally block, so Dispose runs before the exception is caught and printed.
Examine this code snippet:
using System;
class Program {
static void Main() {
using var r = new Resource();
r.Use();
}
}
class Resource {
public void Use() {
Console.WriteLine("Using resource");
}
}Why does this code fail to compile?
using System; class Program { static void Main() { using var r = new Resource(); r.Use(); } } class Resource { public void Use() { Console.WriteLine("Using resource"); } }
Check if the resource type supports disposal.
The 'using var' syntax requires the variable type to implement IDisposable. Here, Resource does not implement IDisposable, so the compiler errors.
Choose the correct syntax to use two disposable resources in a single 'using' statement.
Look for comma-separated declarations inside the using parentheses.
Option B correctly uses comma-separated declarations for multiple resources in a single 'using' statement. Option B nests two 'using' statements. Option B uses sequential 'using var' declarations. Option B has invalid syntax with the semicolon.
Analyze this code:
using System;
class Counter : IDisposable {
public static int count = 0;
public Counter() {
count++;
}
public void Dispose() {
count--;
}
}
class Program {
static void Main() {
using (var c1 = new Counter()) {
using (var c2 = new Counter()) {
// do nothing
}
using (var c3 = new Counter()) {
// do nothing
}
}
Console.WriteLine(Counter.count);
}
}What is printed?
using System; class Counter : IDisposable { public static int count = 0; public Counter() { count++; } public void Dispose() { count--; } } class Program { static void Main() { using (var c1 = new Counter()) { using (var c2 = new Counter()) { // do nothing } using (var c3 = new Counter()) { // do nothing } } Console.WriteLine(Counter.count); } }
Think about when Dispose is called and how it affects the static count.
Each Counter increments count on creation and decrements on Dispose. All three are disposed by the end, so count returns to 0.