Reputation: 838
I want to have one object shared by two classes if they have the same key (it is just a string), so if the value of the object changes it changes in both classes. I think that it will be like having the two objects pointing to the same memory address, so in C it could be done with pointers. To clarify what I want to do I have prepared the next example code:
class MyObject
{
string key;
int value;
public MyObject(string key, int value)
{
this.key = key;
this.value = value;
}
}
class MainClass{
MyObject parameter = new MyObject("key", 5);
List<MyObject> list = new List<MyObject>();
list.Add(parameter);
}
class SecondaryClass{
MyObject parameter = new MyObject("key", 0);
List<MyObject> list = new List<MyObject>();
list.Add(parameter);
}
MainClass mainClass = new MainClass();
SecondaryClass secondaryClass = new SecondaryClass();
foreach (MyObject newParameter in mainClass.list)
{
// Try to find a match in the parameterKey
MyObject parameter = secondaryClass.list.Find(p => p.Key == newParameter.Key);
// If there is a match, update the object
if (parameter != null)
{
parameter = newParameter;
}
}
Console.WriteLine(mainClass.parameter.value) // This output 5
Console.WriteLine(secondaryClass.parameter.value) // This output 0
See that the parameter of the secondaryClass still points to 0, the value has not been updated. It is possible to do this in C#? Maybe sharing the reference?
--- EDIT ---
I include now a Minimal, Complete, and Verifiable example as Jon Skeet requested.
class MyObject
{
public string key;
public int value;
public MyObject(string key, int value)
{
this.key = key;
this.value = value;
}
}
class MainClass
{
public MyObject parameter = new MyObject("key", 5);
public List<MyObject> list = new List<MyObject>();
public MainClass()
{
list.Add(parameter);
}
}
class SecondaryClass
{
public MyObject parameter = new MyObject("key", 0);
public List<MyObject> list = new List<MyObject>();
public SecondaryClass()
{
list.Add(parameter);
}
}
class Program
{
static void Main(string[] args)
{
MainClass mainClass = new MainClass();
SecondaryClass secondaryClass = new SecondaryClass();
foreach (MyObject newParameter in mainClass.list)
{
// Try to find a match in the parameterKey
MyObject parameter = secondaryClass.list.Find(p => p.key == newParameter.key);
// If there is a match, update the object
if (parameter != null)
{
parameter = newParameter;
}
}
Console.WriteLine(mainClass.parameter.value); // This output 5
Console.WriteLine(secondaryClass.parameter.value); // This output 0, I expected 5
mainClass.parameter.value = 7;
Console.WriteLine(mainClass.parameter.value); // This output 7
Console.WriteLine(secondaryClass.parameter.value); // This output 0, I expected 7
}
}
As you can see, the object secondaryClass.parameter is not changed and stills point to the original one. Of course, if it was only one object I could add at the end this two lines:
secondaryClass.parameter = mainClass.parameter;
mainClass.parameter.value = 9;
Console.WriteLine(mainClass.parameter.value); // This output 9
Console.WriteLine(secondaryClass.parameter.value); // This output 9
There are two main problems:
MyObject is more complex than the one showed here, with more attributes inside.
MainClass and SecondaryClass have several objects MyObject and only the ones that have the same key are needed to be shared (and both classes can have MyObject objects not shared).
Upvotes: 2
Views: 3115
Reputation: 24
Have you tried making MyObject class a singleton? Then you can utilize any data structure class such as a HashTable. Reason I suggest to use a Hashtable is because it's threadsafe.
Upvotes: 1
Reputation: 23174
Cause of the problem is described by S. Schenkel : you are merely reassigning the local variable with your current pseudo code.
If you want to update the actual object "referred to", you could, for instance, do the following to access the actual object and change the actual field of interest:
You could access the actual object like this for instance :
if (parameter != null)
{
parameter.value = newParameter.value;
}
However you should make value
a public field or a property with a public setter to be able to do that.
Of course, this is just to get you the idea.
Probably you should do something clearer / better encapsulated like this :
class SecondaryClass
{
public MyObject parameter = new MyObject("key", 0);
public List<MyObject> list = new List<MyObject>();
public SecondaryClass()
{
list.Add(parameter);
}
public UpdateParameter(MyObject newParameter, string key)
{
// here you can write code that can *directly* access your field or list.
// you can, for instance, search for the object by key in the list, delete it from the list, and add `newParameter` to the list
// and reassign "parameter" with this new object.
}
}
Note that you can now defer the burden of searching if the key exist in this "UpdateParameter" method.
your "main" code could become this :
foreach (MyObject newParameter in mainClass.list)
{
// Try to find a match, and update it in the parameterKey
secondaryClass.UpdateParameter(newParameter);
}
Note : I don't understand the idea of using a "list" of parameters, additionally to having a field storing a single parameter.
As suggested, if you have several key-value pairs, you should use a Dictionary<string, MyObject>
as an internal field of your MainClass and SecondaryClass, that would simplify access and readability of your code a lot.
Upvotes: 0
Reputation: 191
With parameter = newParameter
, your are only modifying the reference of MyObject parameter
which is a local variable.
You are not modifying the reference of your object in the list of secondaryClass.
Upvotes: 2