【问题标题】:Using on an object created in a different method在以不同方法创建的对象上使用
【发布时间】:2019-10-26 03:06:19
【问题描述】:

我正在尝试进行通用 SQL 调用,这让我想到了一个有趣的问题。我有一个执行 SQL 并返回 SQLDataReader 的方法。

    private SqlDataReader ExecuteSql(SqlCommand command)
    {
        using (var connection = new SqlConnection(ConnectionText, Credentials))
        {
            command.Connection = connection;
            connection.Open();
            return command.ExecuteReader();
        }
    }

调用命令获取阅读器并正确处理返回的数据。然而,我知道读者需要被处理掉,所以我将其附在 using 声明中。

        using (SqlDataReader reader = ExecuteSql(command))
        {
            while (reader.Read())
            {
                try { ... }
                catch(Exception e) { ... }
            }
        }

我认为 Dispose 应该在 using 语句末尾的 SqlDataReader 上调用,尽管它是在代码中创建的。但是,我无法找到任何具体证实这一点的内容。

概括地说,using 语句能否成功用于在代码中其他地方创建的对象?

作为旁注,我确实意识到如果 SqlDataReader 是在 ExecuteSql 方法中创建为对象而不是直接返回,那么它可能会在 ExecuteSql 中引发异常方法和不被处置。

【问题讨论】:

  • 一般对象的特征不依赖于创建它的代码位置。然而,变量并非如此;诸如保证生命周期do 等变量的特征取决于变量的创建位置。

标签: c# using


【解决方案1】:

您可以通过像这样传递一个 Action 来完成此操作:

private void ExecuteSql(SqlCommand command, Action<SqlDataReader> action)
{
    using (var connection = new SqlConnection(ConnectionText, Credentials))
    {
        command.Connection = connection;
        connection.Open();
        using (var reader = command.ExecuteReader())
        {
            action(reader);
        }
    }
}

然后调用函数:

var myCommand = //...

int id;

ExecuteSql(myCommand, (reader) => {
  id = reader.GetInt32(0);
});

现在任何调用者都不需要知道他们是否必须处理它,并且您的连接将在该方法对读取器完成后处理。

【讨论】:

  • 虽然Zdeslav 回答了 OP 的具体问题,但我认为此答案中建议的架构远远优于 OP 所采用的方法。也就是说,我宁愿使用接受Func&lt;SqlDataReader,T&gt; 的通用private T ExecuteSql&lt;T&gt;。让Func 只处理一行,而不是在ExecuteSql 上使用各种特定于集合的变体,您可以变得更有趣。
  • @Brian 我完全同意。在没有任何上下文的情况下,此解决方案不仅限于SqlDataReader,因为它可以与任何一次性物品一起使用,这更像是我根据问题的标题使用它的地方。
【解决方案2】:

在 using 语句中使用另一个方法中创建的对象是可以的。 但是,在您的情况下,您使用的是 SqlDataReader,它使用了在 ExecuteSql 调用结束时设置的 SqlConnection

正如here 所解释的,您需要一个有效的连接对象才能使用SqlDataReader

【讨论】:

  • 感谢您的回答,并指出我没有发现但应该有的错误。
猜你喜欢
  • 2017-11-26
  • 1970-01-01
  • 2016-09-19
  • 2017-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-28
相关资源
最近更新 更多