Dangerous Using Declaration (C# 8.0)
Tags: csharp, dotnet, programming, bestpractices
Published: 2023-10-09 07:41:34

---
title: Dangerous Using Declaration (C# 8.0)
published: true
date: 2023-10-09 07:00:15 UTC
tags: CSharp, DotNet, Programming, BestPractices
canonical_url: https://zagosk.in/dangerous-using-declaration-csharp-8
---

Today, let's dive into the somewhat unpredictable and potentially risky behavior of the C# 8.0 "Using Declaration" feature. As always, no boring long introduction paragraphs, let's get straight to the point!

## What is Using Declaration?

In C# 7.0 we did this:

```csharp
public void SuperMethod()
{
    using (var myVariable = new SomeDisposable())
    {
        // use myVariable
    } // myVariable will be disposed here
}

```

Since C# 8.0 we can write this as follows:

```csharp
public void SuperMethod()
{
    using var myVariable = new SomeDisposable();
    // use myVariable
} // myVariable will be disposed here

```

The lifetime of `myVariable` will extend to the end of the scope in which it is declared (in this case `SuperMethod` containing method).

Looks marvelous! But only until we combine it with object initializers...

## The Problem

First, we're going to take a look at this tiny piece of code:

```csharp
using var response = new HttpResponseMessage
{
    Content = new StringContent("Hello, World!")
};
// some other code

```

At first glance, it looks perfectly fine: we create an instance of a disposable type and initialize one of its properties. When the program execution reaches the end of the method that contains this code, our `response` object will be disposed (the same goes for when "some other code" throws an exception). In other words, we could expect this behavior:

```csharp
var response = new HttpResponseMessage();
try
{
    response.Content = new StringContent("Hello, World!");
    // some other code
}
finally
{
    response.Dispose();
}

```

While intuition and common sense might lead us to expect this, the reality is quite different.

To understand what happens let's check the "Low-Level C#" and IL for the first code snippet that we started with:

![Low-Level C# for Using Declaration](https://cdn.hashnode.com/res/hashnode/image/upload/v1696683117483/626f625d-0d41-44d6-a30a-75f0a4235d3a.png)

![IL Code for Using Declaration](https://cdn.hashnode.com/res/hashnode/image/upload/v1696683270127/6223e17d-165c-42b3-890a-f3d438214c2f.png)

Now we can see what is wrong with this lovely Using Declaration construction: if we use object initializer on our instance, the values will be assigned to the properties **before** the try-catch block. Thus, if one of these setters throws an exception, we will end up with an allocated instance of a disposable type that is not going to be disposed by the `using` (in the try-catch block).

Frankly, this implementation and design choice caught me off guard.

## Solution

As you might have guessed, the workaround is straightforward: first, instantiate a disposable object using "Using Declaration," and then initialize its properties avoid using object initializers.

## Example

```csharp
using var response = new HttpResponseMessage();
response.Content = new StringContent("Hello, World!");
// some other code

```

![Low-Level C# for Using Declaration (good practice)](https://cdn.hashnode.com/res/hashnode/image/upload/v1696684278049/19e0021e-b245-42b6-a694-99f769515af6.png)

![IL Code for Using Declaration (good practice)](https://cdn.hashnode.com/res/hashnode/image/upload/v1696684371404/82aa697d-9d13-4368-9061-fda9fc6d4942.png)

## Bonus

If you use an advanced IDE (JetBrains Rider) or an amazing plugin for Visual Studio (Resharper), it will warn you about this code issue:

![JetBrains Rider vs wrong C# Using Declaration](https://cdn.hashnode.com/res/hashnode/image/upload/v1696684605636/a67b01f7-8280-4301-8041-2ebdb4e31c1d.png)

> initialize object properties inside the 'using' statement to ensure that the object is disposed if an exception is thrown during initialization

That's all for now. Thank you for reading, I hope it helps!

Cheers!