使用释放对象的属性是否有效

本文关键字:属性 是否 有效 对象 释放 | 更新日期: 2023-09-27 18:31:19

谁能告诉我使用Dispose object的属性是否有效? 例如,在下面的代码中,数据表正在获取处置,但其属性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,我不会收到任何错误。 但在这种情况下,释放对象不是真的 默认视图 释放其所有属性。

使用释放对象的属性是否有效

这取决于类型,但作为一般规则,您应该仅在完成使用该对象时调用Dispose()。如果您在释放对象后尝试访问任何成员,大多数IDisposable实现都会引发ObjectDisposedException

IDisposable没有任何固有的东西会强制实现类在处置时使对所有成员的所有访问无效。

仅当类型专门记录了它允许您在释放后调用某些成员时,才应考虑这样做。就个人而言,我会尽量避免使用以这种方式实现的类型。

请注意,这与对象本身有关,不一定是它引用的对象。也就是说,仅仅因为对象A具有引用其他对象B的属性,这并不意味着该对象B在释放A时变得无效。

一个很好的例子是具有 Socket 属性的 NetworkStream 类。如果将NetworkStream对象初始化为不拥有传递给其构造函数的Socket实例,则Socket实例在释放NetworkStream后仍然有效,这完全没问题。

DataTable类和DataColumn确实实现了IDisposable,但它们的实现不做任何事情。 这些实现IDisposable,因为派生类可能需要释放资源。

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

当您

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

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

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

由于您添加的值不是非托管资源,因此没有理由假定它已被释放。仍然存在对对象的有效引用,因此 GC 不会清除内存。 仔细想想,如果提出例外,那就可怕多了。

C# 在后台具有内存管理功能,因此对于许多程序员来说,它是看不见的。当然,有些事情在野外实现得很差,因为资源管理不是您在 C# 中经常考虑的事情