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.
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;
}
}
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
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.
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.
精彩评论