Whether the object can be collected by GC

Hi all: assuming I got the Class A and B:

class A {
    public string foo = "foo";
    public int a = 10;
    public double d = 3.14;
}

class B {
    public string s;
}

A a = new A();
B b = new B();

b.s = a.foo;

a = null;

// if GC occurs here...

My question is after a is set to null, whether it can be collected by GC at next GC trigger point even though b reference one of its fields, foo?

Thanks for any answer.

Jon Skeet
people
quotationmark

My question is after a is set to null, whether it can be collected by GC at next GC trigger point even though b reference one of its fields, foo?

The value of b.s happens to have been set to a.foo, but that's just copying the value. After the assignment occurs, there's absolutely no connection between the instances of A and B. In particular, any changes to a.foo won't be visible via b.s.

So yes, the instance of A can be garbage collected.

Now, I suspect someone may talk about string being immutable. While this is true, it doesn't actually affect things. Suppose we had:

class A
{
    // We would never really use public fields, of course...
    public StringBuilder x;
}

class B
{
    public StringBuilder y;
}

Then:

A a = new A();
a.x = new StringBuilder("Foo");

B b = new B();
b.y = a.x;
b.y.Append("Bar");
Console.WriteLine(a.x); // Prints FooBar

a = null;

Still, the instance of B does not prevent the instance of A from being garbage collected - because again, assignment has just copied the value from a.x to b.y. That value is a reference to the StringBuilder, so modifying the contents of the StringBuilder via either field results in a change that is visible via the other field, but the fields don't actually "know" about each other.

people

See more on this question at Stackoverflow