我可以将using(){}块与方法';s out参数
本文关键字:方法 参数 out using 我可以 | 更新日期: 2023-09-27 18:15:22
给定一个方法
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
和friends相同的模式,即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变量">
)
不,这是不可能的。
using (x) {...}
构造在进入块时生成x
的副本,因此可以执行以下操作:
var x = new FileStream(...);
using (x)
{
x = null;
}
当using
块结束时,流仍将被丢弃。
必然结果是这也不会起作用:
Stream x = null;
using (x)
{
x = new FileStream(...);
}
在这里,您在using块中构造的流将不会被处理。
然而,你能做的是:
Connection connection;
if (Connection.TryCreate(out connection))
using (connection)
{
}
在C#7.0及以后的版本中,您可以将其与"out variables"组合以形成:
if (Connection.TryCreate(out var connection))
using (connection)
{
}
看起来Try*
模式使用不当(有些人会认为这是反模式(。
不使用TryCreate
,只需使用一个Create
方法,该方法在不成功的情况下抛出异常,并返回创建的连接。
然后你可以做通常的事情:
using(Connection connection = Connection.Create())
{
}
或者,如果您想避免抛出异常和所需的try{}catch{}
,请在无法创建连接时让Create
方法返回null
,并对此进行测试。
你可以这样做:
Connection connection;
if (Connection.TryCreate(out connection))
{
using (connection)
{
…
}
}
但如果你只是在失败时返回null
可能会更好:
using (Connection connection = Connection.Create())
{
if (connection != null)
{
…
}
}
由using
创建的finally
块检查connection
是否为null
,如果是则不执行任何操作。
此外,如果您没有在using
中声明变量,那么它不必是只读的。
否。如果您担心方法调用和使用之间的异常,可以使用try/finaly:
Connection conn = null;
try {
if(!conn.TryCreate(out conn)) return;
...
} finally {
if(conn != null) conn.Dispose();
}
侧身迈出一步?
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
}
}