5

我想了解两者之间的区别

public DataTable ExectNonActQuery(string spname, SqlCommand command)
{
    using (DataTable dt = new DataTable())
    {
        cmd = command;
        cmd.Connection = GetConnection();
        cmd.CommandText = spname;
        cmd.CommandType = CommandType.StoredProcedure;
        da.SelectCommand = cmd;
        da.Fill(dt);
        return (dt);
    }
}

public DataTable ExectNonActQuery(string spname, SqlCommand command)
{
    DataTable dt = new DataTable();
    cmd = command;
    cmd.Connection = GetConnection();
    cmd.CommandText = spname;
    cmd.CommandType = CommandType.StoredProcedure;
    da.SelectCommand = cmd;
    da.Fill(dt);
    return (dt);
    }
}

我实际上想了解使用“使用”创建新对象而不是像这样直接创建它有什么好处

DataTable dt = new DataTable();
4

6 回答 6

16

您的第一个示例不正确:using(var ...)确保在退出时IDisposable.Dispose在内部声明的变量上调用。using因此,您的第一个示例返回一个已处置的对象,这几乎肯定是错误的。

一般来说,这个using块大致相当于这个:

var x = new MyDisposable();
try {
    // Do something with x
} finally {
    x.Dispose();
}

由于这是 C# 中非常常见的模式,因此提供了一种特殊语法以方便您使用。

于 2012-04-28T16:22:59.873 回答
11

using保证对象在 using 语句的末尾被释放

您可以改为手动调用 .Dispose() ,但是使用 .Dispose()using即使您抛出异常,它也会被释放

并且您可以避免自己的错误,例如忘记调用 .Dispose,或者在调用 Dispose 之前重新分配变量。

这一切都在文档中:

http://msdn.microsoft.com/en-us/library/yh598w02.aspx

编辑:另外,正如 dasblinkenlight 在另一个答案中解释的那样,在从函数返回对象时处理它是一个坏主意

但是,在 DataTable、DataSet 和 DataView 的特殊情况下,您实际上并不需要处理这些对象,因此在这个特定示例中,可以安全地忽略 DataTable 是 IDisposable。此外,由于 DataTable 的 .Dispose() 方法明确地什么都不做(最终化被抑制),尽管返回了已处置的对象,您的第一个示例实际上应该可以工作。

请参阅我应该 Dispose() 数据集和数据表吗?

因此,在您的特定示例中,实际差异可能为零。

在可行的情况下,使用 Using 语句包装 IDisposables 通常仍然是一种很好的做法。(如果一个对象必须在函数内部构造,然后在该函数外部访问,这是不可能的。)

于 2012-04-28T16:20:44.773 回答
4
using (DataTable dt = new DataTable())

等于

DataTable dt = new DataTable();
try
{
}
finally 
{
    if(dt != null)
        dt.Dispose()
}

因此,在这种情况下,如果抛出任何异常,您的数据表对象将被释放。在您的情况下,如果为 DataTable 类定义了终结器,则只有在垃圾收集器将收集它时才会处理它

于 2012-04-28T16:25:05.413 回答
1

来自msdn,

定义一个范围,一个或多个对象将被释放到该范围之外。

您无需担心处置您使用的对象的内存/资源。using 语句将解决这个问题。using一旦控件退出语句外部块(范围),在 using 块内定义的变量将自动释放。

典型示例是 SQL 连接。通常,您必须在事务后通过调用 Close 方法显式关闭连接。但是通过使用 statmenet,您不必担心。它会得到照顾。

CLR 通常会在 CLR 决定执行垃圾回收时释放内存。通过使用该using语句,我们手动释放自己使用的内存/资源。

于 2012-04-28T16:24:07.143 回答
1

using使用语句时,您不会以不同的方式创建对象。

using 语句只是包装了一个继承 IDisposable 的对象。当您键入

using (DataTable dt = new DataTable()) { }

from 的返回值DataTable dt = new DataTable()是对 dt 的引用,它进入 using 语句。

所以这也可以写成

DataTable dt = new DataTable();
using (dt) { }

正如其他答案所述,使用语句的原因是变量持有的资源可以在垃圾收集器通常释放它们之前被释放。

于 2012-04-28T16:27:25.787 回答
1

在 using 中声明一个类型需要一个类型来实现 IDisposable,这样一旦对象的定义范围结束,对象就会在 Type 中定义的释放方法的帮助下被清理。

这确实很有趣,因为编译器本身将 using 转换为 try..Finally 语句,就像它将常量转换为它们的值一样。所以 using & try..finally 的行为在运行时是相同的:)。

Use the following link to understand more in depth: http://www.codeproject.com/Articles/6564/Understanding-the-using-statement-in-C

I hope it helps.

于 2012-04-28T18:34:45.017 回答