tags:

views:

75

answers:

4

I want to have multiple objects share a reference through a private field, such that any of the objects can assign to the field, and the updated field will be seen by other objects sharing that reference. What I was originally hoping to do was this:

class SomeObject
{
    private ref DataObject _data;
    public SomeObject(ref DataObject data)
    {
         _data = ref data; // or something similar
    }

    public ChangeData(DataObject newData)
    {
         _data = data;
         // at this point, *other* SomeObject instances that were
         // created with the same reference should also have _data == newData
    }
}

But of course you can't use ref that way: ref is only for method parameters. And a static field won't work, since not all SomeObject instances should refer to the same object---rather, the object in question should be set in the constructor.

Obviously I could solve this by just adding a simple wrapper class. But is there a better way? Is there some kind of SharedReference<T> class that I can use?

Update, since most of the answers misunderstood what I was asking. I know that the _data field contains a reference to the original DataObject. What I want is another level of indirection. I want to be able to change which object I'm pointing to in one instance, and have the new value be picked up by other instances that were created with the same reference. As the updated code sample shows, I want to assign to _data, and effectively change the value of _data in other instances.

+1  A: 

If you simply provide a reference to the object without the ref keyword, you will get the behaviour you want. Using ref is actually passing a reference to a reference (pointer to a pointer), so unless you want to null someone else's reference, it won't be of any use to you.

Update: Sorry I didn't spot that you wanted to re-assign a completely new object into the field and have that reflected throughout. You are best actually creating either a wrapper class to contain the object state and modify that, or a common event that all instances can subscribe to such that when you want to change the object, fire the event with the new object inside it and have each instance update it's own internal reference.

Alternatively, use the Singleton pattern - everyone accesses a publicly available static reference, but unlike the traditional Singleton, you let them change the reference if they want to - so everyone can see the change. This also has the benefit that the objects don't need internal references.

Alternatively again, have the data class expose a method allowing it to consume another data class and copy its state across - like cloning.

Adam
Nope - he wants to reassign the field completely
thecoop
@thecoop drop the down vote.
Adam
@thecoop cheers.
Adam
A: 
ULysses
Nope - he wants to reassign the field completely
thecoop
@thecoop please remove the negative vote. The question was updated _after_ my post, and the initial question was ambiguous. I will update my answer shortly
ULysses
You can delete your own posts - there should be a 'delete' link between 'edit' and 'flag'
thecoop
right, thank you.
ULysses
+1  A: 

You could simply use an array of shared objects, and reassign the array elements:

class SomeObject
{
    // you probably want to make this readonly
    private readonly DataObject[] _data;     

    public SomeObject(DataObject[] data)
    {
         _data = data;
    }

    public void ChangeData(DataObject newData)
    {
        _data[0] = o;
    }

    // and you could define your own accessor property...
    private DataObject Data
    {
        get { return _data[0]; }
        set { _data[0] = value; }
    }
}

Apart from that, I think you'll need to define your own 'holder' class & use that

thecoop
This is the first answer that actually understood the question. Thanks :).
JSBangs
@JS Bangs I didn't spot the assignment part - I immediately read "change state" lol, I've modified my answer. Using an array for this is not a very good way to go IMO, its less readable that the alternatives.
Adam
+4  A: 

I don't know of any class that you can use for this, but I seems quite easy to implement your own SharedReference<T> class.

Something like this:

public sealed class SharedReference<T>
    where T : class
{
    public T Reference
    {
        get; set;
    }
}
Andrew Bezzub
I can use this. I just added an `implicit operator T` for extra convenience.
JSBangs