DinoViehland wrote:

littleguru wrote:


The MyObject instance won't be collected by the GC if you are accessing any fields that held by that instance... otherwise - as said - it would be a heavy CLR (GC) bug!


Just to shed a little light on the situation the typical example of this is using IntPtr's and the Dispose pattern.  Such as:

class MyDisposable : IDisposable {
    private IntPtr _foo;
    public void DoIt() {
        SomePInvokeOperation(_foo);
    }

    ~MyDisposable() {
        Dispose();
    }
    public void Dispose() {
        CloseMyHandle(_foo);
        GC.SuppressFinalization(this);
    }
}

Now you do: new MyDisposable().DoIt();  The IntPtr is read and right after that read there are no longer any references to the MyDisposable() instance.  Before SomePInvokeOperation can run the GC kicks in and collects the MyDisposable class.  Next the finalizer thread runs which runs the finalizer which closes the native resource.  Finally your SomePInvokeOperation runs and is operating on a _foo that is no longer valid.

The worst case scenario here is that you can use this for a handle recycling attack which violates security.  If you're lucky the app is just going to crash.  Anyway, the way to fix this is to put a GC.KeepAlive(this); in DoIt() so that the object survives the lifetime of the call.  But it's really only a problem when you're interacting with native resources which the GC doesn't understand and keep alive its self.  So still not a bug, but a good thing to know about if you're doing any interop programming.


Let's sum up: I'm sure that the first parameter that is passed in with that method is a this pointer... Why would the GC mean that the instance should be collected, if I try to access a member variable later on? If I don't access it, it is fine because I'll never discover that the GC collected it.

I'm accessing a private member of the class in the DoIt method. How can the GC collect the instance that is holding that before I access it. I thought the GC is only collecting if the instance is no longer reachable!

Correct me if I'm wrong!