views:

206

answers:

3

I'm trying to design a class which can update a reference to an object (outside the class) on destruction.

So essentially you create an instance of this object and pass it a reference type (in whichever manner, constructor etc.) and then on destruction of the object the original reference has changed to a reference created by the object.

If I pass a reference by reference (say in construction) I can't figure a way to store this reference (as a reference) for the destructor to update it? For example (pseudo):

class Updater
{
    object privateReference;
    public Updater(ref object externalReference)
    {
        privateReference = externalReference; //is privateReference now a new reference to the original object?
    }

    ~Updater()
    {
        privateReference = new object(); //therefore this isn't 'repointing' the externalReference
    }
}

The key here is I'm not trying to mutate the original 'external' object from this class I'm trying to 'repoint' it, or initialise it if you will.

+4  A: 

You can't do this, basically. ref is only applicable within the method itself, effectively.

It's not at all clear what you want to use this for - could you give us more information so we can suggest alternative designs? Anything which relies on a finalizer is troubling to start with, to be honest...

Jon Skeet
Precisely what I was afraid of! It's an implementation of a profiler I once saw in c++... basically you create a Profiler instance (passing in a variable that gets filled with (in this case) a timespan object as the Profiler falls out of scope. It was very elegant but obviously relied on pointer assignment...
Adam Naylor
Finalizers aren't run when variables fall out of scope though, so that's another reason why it wouldn't work...
Jon Skeet
+1  A: 

Be aware that using a Finalizer like this isn't the same as a destructor in C++.

When the last reference dies (perhaps it it goes out of scope) the object goes onto the Finalizer queue. The GC determines when to call the Finalizer and it could be a long time after the last reference dies.

Matt Breckon
+3  A: 

This won't work because the ref aspect of the constructor parameter only applies inside the constructor.

What I would do is to give the constructor a delegate that can be used to update the thing in question. Also, you should use IDisposable for this (in conjunction with a using block) rather than a finalizer; finalizers shouldn't touch managed objects (they're designed to free unmanaged objects).

class Updater : IDisposable
{
    Action<object> setter;

    public Updater(Action<object> setter)
    {
        this.setter = setter;
    }

    public Dispose()
    {
        setter(new object());
    }
}
Tim Robinson
This is actually the approach the example I'm adapting takes... this is an option but I wanted to decouple it slightly.
Adam Naylor