4

I want to use using statement, but may need to change the value of the variable that I "use" if the object it should point to does not exist.

I thought of something like this (for registry access and 32/64 windows - though this is my current use case, this is a general question):

using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\MS\Platform"))
{
    if (key == null)
        key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\MS\Platform");
    // use key
}

Above code does not compile:

error CS1656: Cannot assign to 'key' because it is a 'using variable'

I can solve this by not using using but try/catch/finally, and/or testing if the registry key exists before using it.

Is there a way to keep using using, with the correct object being disposed afterwards?

3 Answers 3

6

Just take the if out of the using:

var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\MS\Platform");
if (key == null)
        key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\MS\Platform");

//prob best to null check
if (key != null)
{
  using (key)
  {

      // use key
   }
}

Just as an FYI and to explain why you can do this, a using statement is just syntactical sugar for:

readonly IDisposable item;
try
{

}
finally
{
   item.Dispose();
}

Because it's marked as readonly this also explains why you can't assign to it within the using statement.

Sign up to request clarification or add additional context in comments.

4 Comments

Didn't even know that that was possible.
A using statement is just a short cut to a try/finally/dispose. So anything you can do using that syntax you can do using a ....erm...using :) @AndreasReiff
Be warned that updating the variable after putting it in the using does not change what will be disposed. IDisposable variable; using (variable = firstDisposable) { variable = secondDisposable; } This still disposes firstDisposable. It does not dispose secondDisposable.
Yes, the reference is read only. That code (above) is very unsafe, don't do that...
5

Maybe Null coalesce?

using (var key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\MS\Platform") ?? Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Wow6432Node\MS\Platform"))
{

    // use key
}

2 Comments

This expression can be extracted to a separate variable without changing the behaviour, ie var key = ... ?? ...; using(key){...}. If the expression throws, there is no key to dispose anyway. Exceptions thrown between the assignment and the using statement, well, are just as probable as exceptions thrown between the temporary object creation and its assighment to key inside using
Yes good point. You could also easily figure out which value you want to use before the using block and then just wrap the var in the using.
1

Once you enter the using statement, there is no way to modify the Disposable object it refers to:

Within the using block, the object is read-only and cannot be modified or reassigned.

https://msdn.microsoft.com/library/yh598w02.aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.