Reputation: 10294
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"...
Upvotes: 4
Views: 4347
Reputation: 273774
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 IsDisposed=true ('invalid').
So you can Close (== Dispose) a FileStream. You then still have the object, it will just throw when you try to use it.
Upvotes: 3
Reputation: 49245
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.
Upvotes: 0
Reputation: 248269
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.
Upvotes: 0
Reputation: 1796
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.
Upvotes: 0
Reputation: 20706
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).
Upvotes: 1
Reputation: 18363
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.
Upvotes: 0