在以不同方法创建的对象上使用

Using on an object created in a different method

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

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

调用命令接受reader并正确处理返回的数据。但是,知道 reader 需要处理,我将其包含在 using 语句中。

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

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

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

作为旁注,我确实意识到如果 SqlDataReader 是在 ExecuteSql 方法中创建为对象而不是直接返回,那么它可能会抛出异常而在 ExecuteSql 方法中并且没有被处理掉。

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

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

您可以像这样传递一个 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);
});

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