Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I combine a using() {} block with a method's out parameter?

Given a method

public static bool Connection.TryCreate(out Connection connection) {}

And a piece of calling code:

Connection connection;
if (!Connection.TryCreate(out connection))
    // handle failure gracefully.

/*
 * work with connection
 *
 * …
 *
 */

connection.Dispose();

I'm using the same pattern as bool.TryParse and friends, i.e. TryCreate returns whether the operation was successful.

I realize the using() variable needs to be read-only within its block, but is there a way to turn the above into a using() {} block (TryCreate only sets it once), like so:

using (Connection connection)
{
    if (!Connection.TryCreate(out connection))
        // this would leave the using() block prematurely

    /*
     * work with sconnection
     *
     * …
     *
     */
}

(This doesn't compile:

error CS1657: Cannot pass 'connection' as a ref or out argument because it is a 'using variable'

)

like image 254
Sören Kuklau Avatar asked Nov 19 '11 18:11

Sören Kuklau


1 Answers

No, that is not possible.

The using (x) {...} construct makes a copy of x when it enters the block, so you can do this:

var x = new FileStream(...);
using (x)
{
    x = null;
}

The stream will still be disposed when the using block ends.

The corollary is that this won't work either:

Stream x = null;
using (x)
{
    x = new FileStream(...);
}

here the stream you construct inside the using block will not be disposed.

What you can do, however, is this:

Connection connection;
if (Connection.TryCreate(out connection))
    using (connection)
    {
    }

In C# 7.0 and onwards you can combine this with "out variables" to form:

if (Connection.TryCreate(out var connection))
    using (connection)
    {
    }
like image 62
Lasse V. Karlsen Avatar answered Oct 02 '22 12:10

Lasse V. Karlsen