使用Disposing对象的属性是否有效

时间:2014-11-20 04:01:11

标签: c# .net using-statement

任何人都可以告诉我使用Disposing对象的属性是否有效?例如在下面的代码中,DataTable正在获取Dispose,但稍后会使用其属性DefaultView,

public DataView MyView { get; set; }

    private void button2_Click(object sender, EventArgs e)
    {

        using (DataTable table = new DataTable())
        {
            using (DataColumn dc = new DataColumn("s"))
            {
                table.Columns.Add(dc);
                MyView = table.DefaultView;

            }
            Debug.Write(table.Columns[0].ColumnName);
        }
    }

如果我使用MyView,我不会收到任何错误。但是,在这种情况下,Disposing对象处理其所有属性DefaultView是不正确的。

3 个答案:

答案 0 :(得分:2)

这取决于类型,但作为一般规则,只有在完成使用对象后才能调用Dispose()。如果您在处置对象后尝试访问任何成员,则大多数IDisposable实现将抛出ObjectDisposedException

IDisposable没有任何内在因素迫使实施类在处置时使所有成员的所有访问无效。

只有当特定类型的文档允许您在处理完某些成员后才能调用它,您应该考虑这样做。就个人而言,我试图远离使用以这种方式实现的类型。

请注意,这与对象本身有关,不一定是它引用的对象。也就是说,仅仅因为对象A具有引用其他对象B的属性,这并不意味着当您处置{{1}时对象B变得无效}。

一个很好的例子是A类,它具有NetworkStream属性。如果您将Socket对象初始化为不拥有传递给其构造函数的NetworkStream实例,则Socket实例在部署Socket后仍然有效,这是完美的细

答案 1 :(得分:1)

基础DataTableDataColumn执行实现IDisposable,但他们的实现不执行任何操作。这些实现IDisposable,因为派生的类可能需要处理资源。

例如,在当天,我写了一个通用的,强类型的DataTable类。它实际上封装了数据库连接,或者可能是流。在这种情况下,Dispose确实做了一些事情。

答案 2 :(得分:-1)

当您拥有非托管资源时,如果在释放这些资源之前引发异常,则可能会导致问题,从而实现IDisposable接口。

在使用块中使用时,编译器会生成

try{... } 
catch{... } // may be empty, I can't recall at the moment 
finally 
{
   Dispose() ;
} 

由于您添加的值不是非托管资源,因此没有理由认为它已被处理掉。仍然有对该对象的有效引用,因此GC不会清除内存。考虑一下,如果 引发异常,那将会更加可怕。

C#内存管理,所以对于许多程序员来说,它已经不在乎了。肯定有些事情在野外实施得很差,因为资源管理不是你经常在c#中考虑的事情。