【问题标题】:Will I still get the Dispose advanges, if I in a using, initialize with null?如果我在使用中使用 null 进行初始化,我还会获得 Dispose 优势吗?
【发布时间】:2019-08-09 16:56:48
【问题描述】:

我想重构我的SqlDataReader 代码,所以它使用using..

SqlDataReader reader = null;
reader = xdCmd.ExecuteReader();
// use reader..

我可以使用解决方案 1) 在 using 中声明 reader,然后先用 SqlDataReader 对其进行初始化,然后仍然使用提供的 Dispose“功能”吗?或者我是否需要像解决方案 2) 中那样,在 using 中立即进行初始化? 我猜 1) 没问题,但我不确定。

1)

using (SqlDataReader reader = null)
{
    xdCmd.CommandText = $"select * from {tableName}";
    reader = xdCmd.ExecuteReader();
    // use reader..
}

2)

using (SqlDataReader reader = new SqlDataReader(new SqlCommand($"select * from {tableName}"), xdCon))
{
    reader = xdCmd.ExecuteReader();
    // use reader..
}

【问题讨论】:

标签: c# dispose using-statement


【解决方案1】:

与 Rust 不同,C# 语言不包含表达对象“所有权”或生命周期管理概念的语法,因此完全取决于 API 的文档来说明对象的构造函数是否获取其参数的所有权(以及谁可以致电.Dispose())。这不是 C# 编译器可以为您确定的。但是.Dispose() 无论如何实现都必须是幂等的,因此多次(冗余)调用.Dispose() 是没有害处的。

只需遵循堆叠using 语句的 C# 惯用约定:

using( SqlConnection c = new SqlConnection( connectionString ) )
using( SqlCommand cmd = c.CreateCommand() )
{
    await c.OpenAsync().ConfigureAwait(false);

    cmd.CommandText = "SELECT foo, bar FROM baz";

    using( SqlDataReader rdr = await cmd.ExecuteReaderAsync().ConfigureAwait(false) )
    {
        ...
    }
} 

【讨论】:

  • 我从未见过在 using 语句中使用 await 的,很有趣。
【解决方案2】:

对我来说,我更喜欢使用第二种解决方案,它更微妙,或者您可以使用下面的示例:

using (var sqlConnection = new SqlConnection(connection))
{
       using (var command = new SqlCommand(query, sqlConnection))
       {
            using (var read = command.ExecuteReader())
            {
                // process on your read
            }
       }
}

【讨论】:

  • 您可以组合多个不带大括号的 using 语句,这样您的代码就不需要额外的缩进,顺便说一句。
猜你喜欢
  • 1970-01-01
  • 2019-02-17
  • 1970-01-01
  • 2016-08-31
  • 2018-08-12
  • 1970-01-01
  • 2020-03-03
  • 2021-08-10
  • 2019-05-12
相关资源
最近更新 更多