.NET HELP

C# Using (How it Works for Developers)

Published August 15, 2024
Share:

Even if you’re just getting to grips with C#, you’ll likely have already come across the using directive. And if you’re an IronPDF user, you’ll be very familiar with kicking off your code with the namespace using ironpdf.

However, there’s another use for the using keyword. In this guide, we’ll look at the using statement - what it is, how it works, and how it can help you create more efficient code. Let’s dive in!

What is Using in C#?

The using statement in C# is a convenient way to work with resources that implement the IDisposable interface. IDisposable objects typically hold onto unmanaged resources, like file handles or network connections, that need to be released when you're done using them. This is where the using statement comes into play - it helps you to ensure that these resources are properly disposed of after use.

How the Using Statement Works

When you use the using statement, C# will automatically call the Dispose method on the object when it's no longer needed. This means you don't have to manually call the Dispose method or worry about forgetting to do so. The using statement takes care of this for you!

Let's take a look at a simple example to see how the using statement works in action:

using System.IO;

class Program
{
    static void Main()
    {
        using (StreamReader reader = new StreamReader("example.txt"))
        {
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
    }
}
using System.IO;

class Program
{
    static void Main()
    {
        using (StreamReader reader = new StreamReader("example.txt"))
        {
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
    }
}
Imports System.IO

Friend Class Program
	Shared Sub Main()
		Using reader As New StreamReader("example.txt")
			Dim content As String = reader.ReadToEnd()
			Console.WriteLine(content)
		End Using
	End Sub
End Class
VB   C#

In this example, the StreamReader object named reader is wrapped in a using block. When the using block is exited, the Dispose method is automatically called on the reader, freeing up any resources it was holding onto.

Using Block vs. Using Declaration

Starting with C# 8.0, you can use the using declaration instead of the using block. The using declaration is a shorter and more concise way to define a disposable object, like so:

using System.IO;

class Program
{
    static void Main()
    {
        using var reader = new StreamReader("example.txt");
        string content = reader.ReadToEnd();
        Console.WriteLine(content);
    }
}
using System.IO;

class Program
{
    static void Main()
    {
        using var reader = new StreamReader("example.txt");
        string content = reader.ReadToEnd();
        Console.WriteLine(content);
    }
}
Imports System.IO

Friend Class Program
	Shared Sub Main()
		Dim reader = New StreamReader("example.txt")
		Dim content As String = reader.ReadToEnd()
		Console.WriteLine(content)
	End Sub
End Class
VB   C#

With the using declaration, you don't need the curly braces or indentation, making your code more readable. The Dispose method is still called automatically when the variable goes out of scope.

Try Block, Finally Block, and the Using Statement

You might be wondering how the using statement relates to the try and finally blocks in C#. Well, the using statement is actually a shorthand for a try-finally block!

Here's the same example as before, but written using a try-finally block instead of a using statement:

using System.IO;

class Program
{
    static void Main()
    {
        StreamReader reader = null;
        try
        {
            reader = new StreamReader("example.txt");
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
        finally
        {
            if (reader != null)
            {
                reader.Dispose();
            }
        }
    }
}
using System.IO;

class Program
{
    static void Main()
    {
        StreamReader reader = null;
        try
        {
            reader = new StreamReader("example.txt");
            string content = reader.ReadToEnd();
            Console.WriteLine(content);
        }
        finally
        {
            if (reader != null)
            {
                reader.Dispose();
            }
        }
    }
}
Imports System.IO

Friend Class Program
	Shared Sub Main()
		Dim reader As StreamReader = Nothing
		Try
			reader = New StreamReader("example.txt")
			Dim content As String = reader.ReadToEnd()
			Console.WriteLine(content)
		Finally
			If reader IsNot Nothing Then
				reader.Dispose()
			End If
		End Try
	End Sub
End Class
VB   C#

As you can see, the using statement makes the code cleaner and easier to read by removing the need for the try-finally block and the explicit call to the Dispose method.

Managing Multiple Resources

One of the great things about the using statement is that it can handle multiple resources at once. You can stack using statements one after another, or use a single using statement to handle multiple resources in a comma-separated list. Here's an example that demonstrates both approaches:

using System.IO;

class Program
{
    static void Main()
    {
        using (StreamReader reader1 = new StreamReader("example1.txt"))
        using (StreamReader reader2 = new StreamReader("example2.txt"))
        {
            string content1 = reader1.ReadToEnd();
            string content2 = reader2.ReadToEnd();
            Console.WriteLine($"Content from example1.txt:\n{content1}\nContent from example2.txt:\n{content2}");
        }

        // Alternatively, you can use a single using statement with multiple resources:

        using (StreamReader reader1 = new StreamReader("example1.txt"), reader2 = new StreamReader("example2.txt"))
        {
            string content1 = reader1.ReadToEnd();
            string content2 = reader2.ReadToEnd();
            Console.WriteLine($"Content from example1.txt:\n{content1}\nContent from example2.txt:\n{content2}");
        }
    }
}
using System.IO;

class Program
{
    static void Main()
    {
        using (StreamReader reader1 = new StreamReader("example1.txt"))
        using (StreamReader reader2 = new StreamReader("example2.txt"))
        {
            string content1 = reader1.ReadToEnd();
            string content2 = reader2.ReadToEnd();
            Console.WriteLine($"Content from example1.txt:\n{content1}\nContent from example2.txt:\n{content2}");
        }

        // Alternatively, you can use a single using statement with multiple resources:

        using (StreamReader reader1 = new StreamReader("example1.txt"), reader2 = new StreamReader("example2.txt"))
        {
            string content1 = reader1.ReadToEnd();
            string content2 = reader2.ReadToEnd();
            Console.WriteLine($"Content from example1.txt:\n{content1}\nContent from example2.txt:\n{content2}");
        }
    }
}
Imports Microsoft.VisualBasic
Imports System.IO

Friend Class Program
	Shared Sub Main()
		Using reader1 As New StreamReader("example1.txt")
		Using reader2 As New StreamReader("example2.txt")
			Dim content1 As String = reader1.ReadToEnd()
			Dim content2 As String = reader2.ReadToEnd()
			Console.WriteLine($"Content from example1.txt:" & vbLf & "{content1}" & vbLf & "Content from example2.txt:" & vbLf & "{content2}")
		End Using
		End Using

		' Alternatively, you can use a single using statement with multiple resources:

		Using reader1 As New StreamReader("example1.txt"), reader2 As New StreamReader("example2.txt")
			Dim content1 As String = reader1.ReadToEnd()
			Dim content2 As String = reader2.ReadToEnd()
			Console.WriteLine($"Content from example1.txt:" & vbLf & "{content1}" & vbLf & "Content from example2.txt:" & vbLf & "{content2}")
		End Using
	End Sub
End Class
VB   C#

Both of these approaches will ensure that the Dispose method is called on each StreamReader object when the using block is exited, releasing any resources they were holding onto.

Implementing IDisposable Interface

Sometimes, you might create your own custom classes that manage one or more resources. If your class is responsible for handling disposable objects or unmanaged resources, you should implement the IDisposable interface.

Here's an example of a custom class that implements the IDisposable interface:

using System;
using System.IO;

public class CustomResource : IDisposable
{
    private StreamReader _reader;

    public CustomResource(string filePath)
    {
        _reader = new StreamReader(filePath);
    }

    public void ReadContent()
    {
        string content = _reader.ReadToEnd();
        Console.WriteLine(content);
    }

    public void Dispose()
    {
        if (_reader != null)
        {
            _reader.Dispose();
            _reader = null;
        }
    }
}
using System;
using System.IO;

public class CustomResource : IDisposable
{
    private StreamReader _reader;

    public CustomResource(string filePath)
    {
        _reader = new StreamReader(filePath);
    }

    public void ReadContent()
    {
        string content = _reader.ReadToEnd();
        Console.WriteLine(content);
    }

    public void Dispose()
    {
        if (_reader != null)
        {
            _reader.Dispose();
            _reader = null;
        }
    }
}
Imports System
Imports System.IO

Public Class CustomResource
	Implements IDisposable

	Private _reader As StreamReader

	Public Sub New(ByVal filePath As String)
		_reader = New StreamReader(filePath)
	End Sub

	Public Sub ReadContent()
		Dim content As String = _reader.ReadToEnd()
		Console.WriteLine(content)
	End Sub

	Public Sub Dispose() Implements IDisposable.Dispose
		If _reader IsNot Nothing Then
			_reader.Dispose()
			_reader = Nothing
		End If
	End Sub
End Class
VB   C#

In this example, the CustomResource class manages a StreamReader object, which is a disposable object. By implementing the IDisposable interface and implementing a Dispose method, we can use the using statement with instances of this class.

Here's how you would use the using statement with the CustomResource class:

class Program
{
    static void Main()
    {
        using (CustomResource resource = new CustomResource("example.txt"))
        {
            resource.ReadContent();
        }
    }
}
class Program
{
    static void Main()
    {
        using (CustomResource resource = new CustomResource("example.txt"))
        {
            resource.ReadContent();
        }
    }
}
Friend Class Program
	Shared Sub Main()
		Using resource As New CustomResource("example.txt")
			resource.ReadContent()
		End Using
	End Sub
End Class
VB   C#

When the using block terminates, the Dispose method will be called, disposing of the StreamReader object it manages.

Handling Exceptions with the Using Statement

Another benefit of the using statement is that it helps handle exceptions more gracefully. If an exception occurs within the using block, the Dispose method will still be called on the resource, ensuring proper cleanup.

For example, consider the following code:

using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            using (StreamReader reader = new StreamReader("nonexistentfile.txt"))
            {
                string content = reader.ReadToEnd();
                Console.WriteLine(content);
            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
using System;
using System.IO;

class Program
{
    static void Main()
    {
        try
        {
            using (StreamReader reader = new StreamReader("nonexistentfile.txt"))
            {
                string content = reader.ReadToEnd();
                Console.WriteLine(content);
            }
        }
        catch (FileNotFoundException ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
}
Imports System
Imports System.IO

Friend Class Program
	Shared Sub Main()
		Try
			Using reader As New StreamReader("nonexistentfile.txt")
				Dim content As String = reader.ReadToEnd()
				Console.WriteLine(content)
			End Using
		Catch ex As FileNotFoundException
			Console.WriteLine($"Error: {ex.Message}")
		End Try
	End Sub
End Class
VB   C#

In this case, if the code throws a FileNotFoundException, the exception is caught and handled by the catch block. Even though the exception occurred within the using block, the Dispose method is still called on the StreamReader object, ensuring that no resources are leaked.

Working with IronPDF and the Using Statement

IronPDF is a popular library for creating, editing, and extracting PDF files in C# and .NET applications. Like other libraries that work with resources, IronPDF can also benefit from the using statement to ensure proper resource management.

Let's explore how to use the using statement with IronPDF to create a PDF document from an HTML string, demonstrating the power of the using statement in a real-life scenario.

First, make sure you've installed the IronPDF NuGet package in your project:

Install-Package IronPdf

Now, let's extract data all data from the PDF file:

using IronPdf;

class Program
{
    static void Main()
    {
        using (PdfDocument pdfDocument = PdfDocument.FromFile("PDFData.pdf"))
        {
            string extractedText = pdfDocument.ExtractAllText();
            Console.WriteLine(extractedText);
        }
    }
}
using IronPdf;

class Program
{
    static void Main()
    {
        using (PdfDocument pdfDocument = PdfDocument.FromFile("PDFData.pdf"))
        {
            string extractedText = pdfDocument.ExtractAllText();
            Console.WriteLine(extractedText);
        }
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main()
		Using pdfDocument As PdfDocument = PdfDocument.FromFile("PDFData.pdf")
			Dim extractedText As String = pdfDocument.ExtractAllText()
			Console.WriteLine(extractedText)
		End Using
	End Sub
End Class
VB   C#

In this code, we open a PDF file named "PDFData.pdf" using the PdfDocument.FromFile method. This method returns a PdfDocument instance, which we wrap in a using statement.

Inside the using block, we call ExtractAllText on the PdfDocument instance to extract all text from the PDF. When the using block is exited, the Dispose method is automatically called on the PdfDocument, releasing any resources it was holding onto.

By using the using statement with PdfDocument, we ensure that the PDF file is properly closed after we're done extracting text from it, even if an exception occurs during the process. This is a good example of how the using statement can help manage resources effectively in C#.

Csharp Using 1 related to Working with IronPDF and the Using Statement

Wrapping Up

And that’s a whistle stop tour of the using statement! We've seen how it ensures the efficient handling of disposable objects, managing one or several resources seamlessly. The using statement not only aids in maintaining cleaner code but also enhances the readability of your C# project.

We also introduced IronPDF, a robust library for PDF manipulation in C#. Employing the using statement in conjunction with IronPDF demonstrates this code feature's practical application, reinforcing the concept and its importance.

Ready to get your hands on IronPDF? You can start with our 30-day free trial of IronPDF and Iron Software's Suite. It’s also completely free to use for development purposes so you can really get to see what it’s made of. And if you like what you see, IronPDF starts as low as $749 for licensing options. For even bigger savings, check out the Iron Suite complete software package where you can get all nine Iron Software tools for the price of two. Happy coding!

Csharp Using 2 related to Wrapping Up

< PREVIOUS
C# Extension Methods (How It Works For Developers)
NEXT >
What is Visual C++ Redistributable

Ready to get started? Version: 2024.12 just released

Free NuGet Download Total downloads: 11,781,565 View Licenses >