我可以将using(){}块与方法的out参数组合使用吗?

Sör*_*lau 11 c# using-statement .net-3.5

给定一种方法

public static bool Connection.TryCreate(out Connection connection) {}
Run Code Online (Sandbox Code Playgroud)

还有一段调用代码:

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

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

connection.Dispose();
Run Code Online (Sandbox Code Playgroud)

bool.TryParse和朋友使用相同的模式,即TryCreate返回操作是否成功.

我意识到using()变量需要在其块内是只读的,但有没有办法将上面变成一个using() {}块(TryCreate只设置一次),如下所示:

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

    /*
     * work with sconnection
     *
     * …
     *
     */
}
Run Code Online (Sandbox Code Playgroud)

(这不编译:

错误CS1657:无法将'connection'作为ref或out参数传递,因为它是'using variable'

)

ang*_*son 5

不,那是不可能的。

using (x) {...}结构使得副本x,当它进入块,所以你可以这样做:

var x = new FileStream(...);
using (x)
{
    x = null;
}
Run Code Online (Sandbox Code Playgroud)

using块结束时,流仍将被丢弃。

结果是,这也不起作用:

Stream x = null;
using (x)
{
    x = new FileStream(...);
}
Run Code Online (Sandbox Code Playgroud)

在这里,您在using块内构造的流不会被丢弃。

但是,您可以执行以下操作:

Connection connection;
if (Connection.TryCreate(out connection))
    using (connection)
    {
    }
Run Code Online (Sandbox Code Playgroud)

在C#7.0及更高版本中,您可以将其与“输出变量”组合形成:

if (Connection.TryCreate(out var connection))
    using (connection)
    {
    }
Run Code Online (Sandbox Code Playgroud)


Ode*_*ded 4

看起来该模式的使用不当Try*(有些人认为这是一种反模式)。

而不是 a TryCreate,只需使用一个Create方法,如果不成功,则抛出异常并返回创建的连接。

然后你可以做通常的事情:

using(Connection connection = Connection.Create())
{
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您想避免引发异常和 required try{}catch{},请让该方法在无法创建连接时Create返回并进行测试。null