Object pointer management in C# (from a C++ perspective)

G

Giovanni Dicanio

Hi,

please consider the following scenario:

I allocate some objects in C# using new.
e.g.:

MyObject x = new MyObject();

then I assign this object to several places, e.g. in Tag field in
ListViewItem, in some collection like List<MyObject>, etc.
The point is that the same 'x' is assigned to several different places.

If I clear the listview control, can I be sure that the List<MyObject>
container still stores reference to 'x' object?

And if I clear the List<MyObject> container, can I be sure that the listview
control ListViewItem.Tag field stores valid reference to 'x' object?

The point is that I have a C++ background, and in C++ I can explicitly
control pointers to objects (or use smart pointers wrappers like
shared_ptr<T> template), instead C# abstracts all that from me.

I'd like know if I can trust the C# run-time in scenarios like one described
above, i.e. the garbage collector does not destroy objects that I'm using in
other contexts of the same application.

Or is there some kind of explicit reference counting mechanism that I should
use in C#, like COM IUnknown::AddRef and Release?
i.e. should I call something like x.AddRef() when I store 'x' somewhere, and
x.Release() when I do not need 'x' anymore in that particular place?

Last question:
Is it possible to have RAII in C#?
(This could be useful for classes that manage resources like a file...)
Is 'using' keyword the only option in C# for something similar to C++ RAII?

Thank you very much,
Giovanni
 
M

Mattias Sjögren

If I clear the listview control said:
container still stores reference to 'x' object?
Yes


And if I clear the List<MyObject> container, can I be sure that the listview
control ListViewItem.Tag field stores valid reference to 'x' object?
Yes


Last question:
Is it possible to have RAII in C#?
(This could be useful for classes that manage resources like a file...)
Is 'using' keyword the only option in C# for something similar to C++ RAII?

Yes, using is the way to go.


Mattias
 
P

Peter Duniho

[...]
MyObject x = new MyObject();

then I assign this object to several places, e.g. in Tag field in
ListViewItem, in some collection like List<MyObject>, etc.
The point is that the same 'x' is assigned to several different places.

If I clear the listview control, can I be sure that the List<MyObject>
container still stores reference to 'x' object?

Yes, of course.
And if I clear the List<MyObject> container, can I be sure that the listview
control ListViewItem.Tag field stores valid reference to 'x' object?

The point is that I have a C++ background, and in C++ I can explicitly
control pointers to objects (or use smart pointers wrappers like
shared_ptr<T> template), instead C# abstracts all that from me.

A reference type variable is pretty much the same as a pointer here.
In fact, I'm pretty sure it's stored as a pointer.
I'd like know if I can trust the C# run-time in scenarios like one described
above, i.e. the garbage collector does not destroy objects that I'm using in
other contexts of the same application.

The whole point of the garbage collector is to _only_ collect an object
when there are no longer any references to it. So of course, if you
have stored a reference to an object it won't be collected.

If anything, the opposite problem is more typical, with a programmer
forgetting that they have written code to store a reference somewhere,
and accidently causing object lifetimes to be extended beyond what they
should be.
Or is there some kind of explicit reference counting mechanism that I should
use in C#, like COM IUnknown::AddRef and Release?
i.e. should I call something like x.AddRef() when I store 'x' somewhere, and
x.Release() when I do not need 'x' anymore in that particular place?

No. The whole point of the C# memory model is to avoid that.
Last question:
Is it possible to have RAII in C#?
(This could be useful for classes that manage resources like a file...)
Is 'using' keyword the only option in C# for something similar to C++ RAII?

Basically, yes. And note that "using" is really no different from
writing your own try/finally block.

Of course, depending on your definition of "RAII" something as simple
as error-checking and using a "goto" statement _could_ be considered
"RAII". That's also supported in C#.

C# objects don't have destructors. Classes aren't ever stored on the
stack anyway, so only structs would provide something like this
internal to to the class, and they don't have anything that provides a
mechanism to execute some code as the struct goes out of scope.

So, sure...it's possible to have RAII-like behavior in C#, but
depending on your definition of "RAII" you may not be able to implement
it exactly as you're expecting to or would like to.

Pete
 
A

Arne Vajhøj

Peter said:
The whole point of the garbage collector is to _only_ collect an object
when there are no longer any references to it. So of course, if you
have stored a reference to an object it won't be collected.

Objects can be GC'ed even though there are references to them.

Objects are GC'ed when they are not reachable.

This avoid memory leaks of the type where the only reference to A is
in B and the only reference to B is in A.

But to the original question: yes - it works. I have never heard
about a bug where objects got GC'ed that were not supposed to. That
does not preclude that such a bug has existed in the past or will
in the future. But it is extremely unlikely. About the same
chance that a C++ new will allocate the same memory twice due to
a bug in the implementation.

Arne
 
G

Giovanni Dicanio

But to the original question: yes - it works.

Thank you all for all your answers.
I have never heard
about a bug where objects got GC'ed that were not supposed to.

I'd like to clarify that I have not experienced any bug about that.
I was just asking to be sure about this aspect of C# memory management.

Giovanni
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top