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

时间:2011-11-19 18:25:55

标签: c# .net-3.5 using-statement

给出方法

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

和一段调用代码:

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

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

connection.Dispose();

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

我意识到using()变量需要在其块内是只读的,但有没有办法将上面的内容转换为using() {}块(TryCreate只设置一次) ,像这样:

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

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

(这不编译:

  

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

5 个答案:

答案 0 :(得分:4)

看起来好用Try*模式(有些人认为这是反模式)。

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

然后你可以照常做到:

using(Connection connection = Connection.Create())
{
}

或者,如果要避免抛出异常和所需的try{}catch{},请在无法创建连接时让Create方法返回null并对其进行测试。 / p>

答案 1 :(得分:3)

不,这是不可能的。

using (x) {...}构造在进入块时会复制x,因此您可以执行此操作:

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

using块结束时,仍将处理流。

然而,你可以做的是:

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

答案 2 :(得分:2)

你可以这样做:

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

但如果您在失败时返回null可能会更好:

using (Connection connection = Connection.Create())
{
    if (connection != null)
    {
        …
    }
}

finally创建的using块会检查connection是否为null,如果是using则不会执行任何操作。

另外,如果您没有在{{1}}中声明变量,那么它不必是只读的。

答案 3 :(得分:1)

没有。如果您担心方法调用和使用之间的差异,可以使用try / finally:

Connection conn = null;
try {
    if(!conn.TryCreate(out conn)) return;
    ...
} finally {
    if(conn != null) conn.Dispose();
}

答案 4 :(得分:0)

横向走一步?

public class ConnectTo : IDisposable
{

  public Connection CurrentConnection {get; private set;}

  public ConnectTo()
  {
    CurrentConnection = null;
    // Connect up to whatever.
  }


  #region IDisposable

  // Blah blah

  #endregion
}

然后

using( ConnectedTo conn = new ConnectTo())
{
  if (conn.CurrentConnection != null)
  {
    //Do Stuff
  }
}