C# 仅在using语句范围内创建和使用时的对象生存期

C# 仅在using语句范围内创建和使用时的对象生存期,c#,dapper,C#,Dapper,当对象仅在using语句的范围内创建和使用时,是否在处理其封闭的IDisposable实例的过程中处理该对象?如果不是,为什么不是呢 例如,在使用Dapper时,我经常在SqlConnection的范围内创建一个匿名对象,给人的印象是它会很快被处理掉——但我最近读到了一些相反的东西 using (var connection = new SqlConnection("Connection String")) { var parameters = new { Me

当对象仅在using语句的范围内创建和使用时,是否在处理其封闭的
IDisposable
实例的过程中处理该对象?如果不是,为什么不是呢

例如,在使用Dapper时,我经常在
SqlConnection
的范围内创建一个匿名对象,给人的印象是它会很快被处理掉——但我最近读到了一些相反的东西

using (var connection = new SqlConnection("Connection String"))
{
    var parameters = new
    { 
        Message = "Hello world!"
    };

    connection.Execute("INSERT INTO...", parameters);
}

您的
使用
语句实质上等同于:

 var connection = new SqlConnection("Connection String");

 try
 {
     var parameters = new
     { 
         Message = "Hello world!"
     };
 }
 finally
 {
     if (connection != null)
     {
         ((IDisposable)connection).Dispose();
     }
 }
如您所见,没有理由自动为您释放在
try
块中创建的任何其他
IDisposable
实例。如果确实需要确保释放其他对象,则只需使用语句嵌套

using (var connection = new SqlConnection("Connection String"))
{
     using (var otherDisposableObject = new ....)
     {
     } //otherDisposableObject disposed
} //connection disposed
如果过多的嵌套妨碍了可读性,那么您可以简单地编写using语句,如下所示:

using (var connection = new SqlConnection("Connection String"))
using (var otherDisposableObject = new ....)
using (var anotherDisposableObject = new ....)
using (var andAnotherDisposableObject = new ....)
{
} //andAnotherDisposableObject, anotherDisposableObject, otherDisposableObject and connection all disposed
请记住,您似乎将垃圾收集与处理对象混为一谈。在您的示例中,
参数
可在执行退出
using
语句后用于垃圾收集,因为它没有活动引用

当垃圾回收由
GC
完成时,它很可能永远不会被垃圾回收,这取决于应用程序的内存压力。如果它是垃圾收集的,那么它将被标记为有效的终结器,并且对象的终结器将被安排运行。同样,如果发生这种情况以及何时发生完全取决于
GC

最后,如果正确实现了对象的
IDisposable
模式,并且运行了终结器,则将调用
Dispose()
(准确地说,将调用
Dispose(false)
),对象将处置其可能持有的任何非托管资源(在这种情况下,无法安全地处置托管资源,但这并不重要,
GC
最终也会处理它们)


有关其工作原理的更多详细信息,请参阅,甚至更好,请查看此优秀的。

您可以在
using
语句外部声明
参数
变量,然后您可以稍后访问它。只有
连接
不会处理您在
using
-语句内部初始化或使用的所有内容。它不会使用
处理
中的所有内容是有道理的。这是有道理的,但在我不需要访问匿名对象的情况下,我会认为当作用域结束时它会被垃圾收集。我对其推理很好奇。不要将垃圾收集与处理混淆。当它结束时,它会被垃圾收集s不再被引用(似乎是这样)。
Dispose
另一方面使您能够清理GC不会清理的非托管资源…vs.+1:如果您愿意,请稍加更正,“…并且将计划运行对象的终结器。再次,当发生这种情况时”,可能是“如果发生这种情况,请再说一遍”,因为无法保证终结器会运行。@BinaryWorrier True!修复了这个问题。谢谢你,谢谢你的全面回答!这当然解释了很多,符合我目前对可支配资源和垃圾收集的理解。