C#中的“using”关键字与数据集

时间:2012-05-29 07:14:51

标签: c# .net interface dataset

我对IDisposable接口和C#中的using关键字有一点混淆,我们可以在哪些类上使用它。

using (DataSet studentDS = GetMyStudentDS())
{
    // here comes some code
}

我发现从DataSet类继承的类没有被垃圾收集器最终确定,如果是这样的话,最好将它放在using块中,以便在完成任务后手动完成。有人可以为了所有人的利益而简要介绍一下。感谢。

6 个答案:

答案 0 :(得分:4)

我个人不会将它用于DataSet。当我需要关闭连接并处理它时,我会使用using语句,例如文件阅读器,数据库或SharePoint连接。 C#是一种托管语言,CLR将为您处理垃圾收集,在使用DataSet的情况下,我仍然会遵循这一原则(让CLR为您完成)。

http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.80).aspx

http://www.w3enterprises.com/articles/using.aspx

答案 1 :(得分:3)

  
    

将它放在使用块

中是一个好习惯   

是的。由于DataSet实现了IDisposible接口。 DataSet扩展了MarshalByValueComponent类。 MarshalByValueComponent类实现了IDisposable。

任何派生类型也将实现IDisposable。如果它没有显式实现(换句话说覆盖IDisposable.Dispose),将调用基本方法(DataSet.Dispose)。

关于Finalizer,这是一个单独的概念,即使开发人员无法调用Dispose方法(或忘记使用阻止),也要确保清理非托管资源。

答案 2 :(得分:2)

终结器(析构函数)和IDisposable模式之间存在差异。 GC在非确定性时间调用终结器,用于清除与类关联的非托管资源并释放实例占用的内存。析构函数运行时,它无法控制。

IDisposable用于在确定的时间清理对象。它不会释放对象占用的内存,但它通常用于关闭文件,数据库连接......

因此,一般规则是,如果一个对象实现了IDisposable,最好将其实例包装在using关键字中,以便尽快释放资源。

答案 3 :(得分:0)

DataSet实现了IDisposable,但是他们压制了他们的终结 所以它真的不需要,它们不会引入任何非托管代码 不要用using语句包装它,但不要忘记在sql连接或数据读取器周围使用using关键字。

答案 4 :(得分:0)

C#允许您对实现using的所有内容使用IDisposable。为什么?因为使用只是一种语法糖。 using(obj){/*somecode*/}实际上是这样的:

try
{
    /*somecode*/
}
finally
{
    if(obj!=null) obj.Dispose();
}

如果您使用的是键入的DataSet您可能已经注意到自动生成的类不会覆盖Dispose(bool)。因此Dispose对您自动生成的表和列没有任何作用。 为了帮助您的数据设置可用内存(并且它确实存在问题),请在自动生成的TypedDataSet(部分文件)中覆盖Dispose(bool)。做这样的事情:

protected override void Dispose(bool disposing)
{
    foreach (DataTable tab in this.Tables)
    {
        if (tab != null)
        {
            tab.Clear();
            tab.Columns.Clear();
            tab.Dispose();
        }
    }
    this.Tables.Clear();
    base.Dispose(disposing);
}

现在在using上使用SataSet会有意义。

答案 5 :(得分:-1)

  

是的,绝对可以使用任何对象初始化代码   块。使用它没有任何副作用。在任何情况下,如果   你想100%确定一个对象的垃圾收集保持它   在使用块。