views:

62

answers:

6

Say I have the following class...

Class1
{
  private ArrayList myList;

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

  public ArrayList GetList()
  {
    return myList;
  }
}

Then say in some other class you have the following code...

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

Now, myFavoriteFoo is actually a reference to the Foo that exists in the arraylist in Class1. What will happen if something inside Class1 removes that specific Foo from the class or disposes of it? Will myFavoriteFoo immediately = null? I am guessing if I tried to access Foo.SomeMethod() I would just get an exception like "Object reference not set to an instance of an object"...

+2  A: 

The answer is that it cannot happen.

dotNet offers type-safety: a reference always points to a valid instance or it is null, no other options. That is why there is no manual memory management in dotNet (no delete).

So if your code is holding a reference to an object somewhere then that reference blocks it from garbage collection.

And Dispose() is something else, it has nothing to do with the memory an object occupies. Dispose() is a cleanup for (unmanaged) resources and usually the object will set its internal state to 'invalid'.

Henk Holterman
@Henk - Actually if properly implemented for unmanaged resources, then `the garbage collector automatically releases the memory allocated to a managed object when that object is no longer used.` http://msdn.microsoft.com/en-us/library/system.idisposable.aspx. It's important to note that one could implement `IDisposable` but might not actually use unmanaged resources.
TheCloudlessSky
@TheCloud: The GC automatically releases _all_ managed objects, nothing to do with unmanaged resources.
Henk Holterman
A: 

If the object get's set to null after myFavoriteFoo has a reference to it, myFavoriteFoo still holds the reference. If Foo properly implements IDisposable then you will get an exception if you try to access it after Dispose() is called on the object.

TheCloudlessSky
A: 

Reference objects will not be deleted while there are references pointing to them (with a few exceptions you don't have to worry about). When the original reference goes out of scope, the other reference will still point to your object, and the object will remain alive. After you drop the second reference (by setting it to null, assigning it a different value, or having it run out of scope), the GC may collect it (but isn't guaranteed to do so immediately).

tdammers
A: 

First of all you need to read about reference types. You can try to write the code yourself to see what happens if you're not lazy :)

The true behavior is that if someone deletes the object from the list it doesn't mean that object is deleted from memory. Garbage Collector checks if object has references on it, and in your case myFavoriteFoo holds the reference, so GC will not delete the object.

In case of disposal - in C# there is no way to force delete object manually, even if you call dispose or destructor, the object is checked by the Garbage Collector, and object will be deleted ONLY if it has 0 references to it.

This is true for regular references. Also in .Net there is class WeakReference which overrides rules for regular reference.

anderhil
A: 

Class1 doesn't own the ArrayList itself. It simply holds a reference to it. Both myFavoriteFoo and myClass.myList are references to an ArrayList.

So all the class can do is set its own reference to null. But that doesn't delete the ArrayList. It just means there's one fewer references to it.

But as long as there is at least one reference, the ArrayList is not deleted. So the situation you describe can never happen.

jalf
A: 

myFavoriteFoo is another (apart from one from array) reference to your object. As long as reference is alive, the object won't be garbage collected. So removing the element from array in Class1 does not affect myFavoriteFoo reference - it remains alive. On the other hand, if the object is disposed (via dispose/close call) inside Class1 then you may get error if you try to use its method - the error would be something like that object has been already disposed.

VinayC