JSBձոգչ
JSBձոգչ

Reputation: 41378

Sharing a reference between objects

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.

Upvotes: 4

Views: 2528

Answers (4)

ULysses
ULysses

Reputation: 978

In C#,


class SomeObject
{
    private DataObject _data;
    public SomeObject(DataObject data)
    {
         _data = data;
    }
}

in fact does exactly what you want, if DataObject is a Reference Type, which is true for all classes.

Please disregard this answer since I misunderstood the initial question.
Other answers here cover the topic fully.

Upvotes: 0

Andrew Bezzub
Andrew Bezzub

Reputation: 16032

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;
    }
}

Upvotes: 5

Adam Houldsworth
Adam Houldsworth

Reputation: 64487

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.

Upvotes: 1

thecoop
thecoop

Reputation: 46098

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

Upvotes: 1

Related Questions