首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在“`using`”语句中内联创建的所有对象是否都会被释放?

在“`using`”语句中内联创建的所有对象是否都会被释放?
EN

Stack Overflow用户
提问于 2014-02-18 20:32:38
回答 3查看 3.2K关注 0票数 11

这可能在其他地方得到回答,但在进行了一些搜索之后,我在正常的using上下文之外并没有找到太多关于这个主题的内容。

我很好奇是否所有在using块中创建的对象都会和原始对象一样被释放。

这里是上下文:

通常我会做这样的事情:

代码语言:javascript
代码运行次数:0
运行
复制
using (var conn = new SqlConnection(connectionString))
using (var cmd = new SqlCommand(commandText, conn))
{
    //Do everything I need to here
}

我知道conncmd在这一点上都超出了范围,并且因为可爱的using关键字而被释放。

我很好奇,同样的处置规则是否适用于以下声明:

代码语言:javascript
代码运行次数:0
运行
复制
using (var cmd = new (SqlCommand(commandText, new SqlConnection(ConnectionString)))
{
   //Do everything I need here
}

SqlConnection超出作用域并由于与对象关联而被释放时,using语句中内联创建的cmd对象会被释放吗?

另外,哪一种在语法上是首选的?我个人认为第二个更干净,但我知道可读性也可能在这里发挥。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-02-18 20:34:26

对于第二段代码,当流离开Dispose块时,不会在SqlConnection实例上调用using,除非SqlCommand.Dispose()在内部这样做(不,它没有)。

根据规范(8.13),将using (ResourceType resource = expression) statement转换为:

代码语言:javascript
代码运行次数:0
运行
复制
{
    ResourceType resource = expression;
    try {
        statement;
    }
    finally {
        if(resource != null)
            ((IDisposable)resource).Dispose();
    }
}

在您的代码中,resourceSqlCommand,这是调用Dispose的一个。

票数 10
EN

Stack Overflow用户

发布于 2014-02-18 20:35:10

不是的。

using语句只应用于语句中直接声明的资源,而不应用于初始化程序中的其他分配。

对于每个资源,您需要一个单独的using语句。

票数 4
EN

Stack Overflow用户

发布于 2014-02-18 20:41:15

根据MSDN,此代码:

代码语言:javascript
代码运行次数:0
运行
复制
using (var temp = obj)
{
    // ...
}

翻译为(包括额外的花括号以限制范围):

代码语言:javascript
代码运行次数:0
运行
复制
{
    var temp = obj;
    try
    {
        // ...
    }
    finally
    {
        if (temp != null)
            ((IDisposable)temp).Dispose();
    }
}

如您所见,如果您将obj替换为new SqlCommand(commandText, new SqlConnection(ConnectionString)),那么只有SqlCommand才会得到正确的处理。

代码语言:javascript
代码运行次数:0
运行
复制
{
    SqlCommand temp = new SqlCommand(commandText,
        new SqlConnection(ConnectionString));
    try
    {
        // ...
    }
    finally
    {
        if (temp != null)
            ((IDisposable)temp).Dispose();
    }
}

因此,除非已释放的SqlConnection这样做,否则SqlCommand不会被释放。但是它没有,也不应该:它没有创建对象,因此它也不能破坏它。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21864676

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档