2010-08-12 187 views
2

说我有下面的类...如果引用的对象被删除,引用变量会发生什么?

Class1 
{ 
    private ArrayList myList; 

    private Class1 
    { 
    // Here fill myList with a bunch of Foo objects. 
    } 

    public ArrayList GetList() 
    { 
    return myList; 
    } 
} 

你有下面的代码一些其他类的然后说...

Class1 myClass = new Class1(); 
Foo myFavoriteFoo = myClass.GetList()[0] As Foo; 

现在,myFavoriteFoo实际上是对富的引用存在于Class1中的数组列表中。如果Class1内的某些内容从类中删除特定的Foo或将其丢弃,会发生什么? myFavoriteFoo立即= null?我猜如果我试图访问Foo.SomeMethod()我只会得到一个异常,如“对象引用未设置为对象的实例”...

回答

2

答案是它不能发生。

dotNet提供类型安全性:引用总是指向一个有效的实例,或者它是空的,没有其他选项。这就是为什么dotNet中没有手动内存管理(不删除)的原因。

因此,如果您的代码持有对某个对象的引用,那么该引用会阻止垃圾回收。

And Dispose()是别的东西,它有什么也没有与一个对象占用的内存有关。 Dispose()是对(非托管)资源的清理,通常对象将其内部状态设置为“无效”。

+0

实际上,如果为非托管资源正确实施,那么垃圾收集器会在不再使用该对象时自动释放分配给托管对象的内存。http://msdn.microsoft.com/zh-cn/library/ system.idisposable.aspx。需要注意的是可以实现'IDisposable',但实际上可能不会使用非托管资源。 – TheCloudlessSky 2010-08-12 12:02:46

+0

@TheCloud:GC自动发布_all_托管对象,与非托管资源无关。 – 2010-08-12 12:23:04

0

如果对象获取的设置为null myFavoriteFoo具有对它的引用myFavoriteFoo仍占据参考。如果Foo正确实现了IDisposable,那么如果在对象上调用Dispose()后尝试访问它,则会发生异常。

0

引用对象不会被删除,同时有引用指向它们(有几个例外,你不必担心)。当原始引用超出范围时,其他引用仍将指向您的对象,并且该对象将保持活动状态。在删除第二个引用(通过将其设置为null,为其分配一个不同的值或使其超出范围)之后,GC可能会收集它(但不能保证立即执行此操作)。

0

首先您需要阅读有关参考类型。你可以尝试自己编写代码,看看如果你不懒惰会发生什么:)

真实的行为是,如果有人从列表中删除对象,并不意味着该对象从内存中删除。垃圾收集器检查对象是否具有引用,在您的情况下,myFavoriteFoo保存引用,因此GC不会删除该对象。

在处置的情况下 - 在C#中,无法手动强制删除对象,即使您调用dispose或析构函数,对象也会被垃圾收集器检查,并且对象只有在引用0时才会被删除它。

这是正确的参考。在.Net中也有WeakReference类,它覆盖了规则引用的规则。

0

Class1不拥有ArrayList本身。它只是提到它。 myFavoriteFoomyClass.myList都是引用到ArrayList。

所以所有班级所能做的就是将其自己的引用为null。但是这并不会删除ArrayList。这意味着只有一个参考。

但只要至少有一个引用,ArrayList不会被删除。所以你描述的情况永远不会发生。

0

myFavoriteFoo是另一个(除了一个数组)引用您的对象。只要参考是活的,对象将不会被垃圾收集。因此,从Class1中的数组中移除元素不会影响myFavoriteFoo引用 - 它仍然处于活动状态。另一方面,如果在Class1中处理对象(通过处理/关闭调用),那么如果尝试使用它的方法,则可能会出错 - 错误将会像该对象已经处理过的那样。

相关问题