- Home /
The question is answered, right answer was accepted
Property (set) does not work with reference c#.
I recently discovered that when I keep a reference to a property, then set it. set property has not been called. Does anyone know why?
public class AttributeComponent : MonoBehaviour
{
[SerializeField]
private bool isLinker;
public AttributeDictionary AttributeDictionary
{
get { return attributeDictionary; }
set
{
Debug.Log("Set ");
if (attributeDictionary != value)
{
if (isLinker)
{
LinkerComponent linkerComponent = GetComponent<LinkerComponent>();
linkerComponent.RemoveAllLinker(attributeDictionary);
attributeDictionary = value;
attributeDictionary.CalculateValueOfAllAttribute();
linkerComponent.AddAllLinker(attributeDictionary);
}
else
{
attributeDictionary = value;
attributeDictionary.CalculateValueOfAllAttribute();
}
}
}
}
}
// This does not work.
Attribute_Component = Character_Component.GetComponent<AttributeComponent>();
AttributeDictionary attributeDictionary = Attribute_Component.AttributeDictionary;
attributeDictionary = LoadAttribute(slot);
// This work.
Attribute_Component = Character_Component.GetComponent<AttributeComponent>();
Attribute_Component.AttributeDictionary = LoadAttribute(slot);
Answer by fafase · Apr 15, 2018 at 10:01 AM
Attribute_Component = Character_Component.GetComponent<AttributeComponent>();
At this point above you have a reference to the script with the property.
AttributeDictionary attributeDictionary = Attribute_Component.AttributeDictionary;
Above again, you have a reference (attributeDictionary) and you assign the return value of the property. At this point, using attributeDictionary is pointing to the object the property returns, but not the property itself.
attributeDictionary = LoadAttribute(slot);
Finally, you are assigning a new value, that won't affect the property. That reference has no link to the property. If you want to trigger the property then call it directly. No other way since you cannot pass a property by reference. You could use a delegate that calls the property within, but that sounds like added complexity.
public void Method(AttributeDictionary ad){ AttributeDictionary = ad; }
Action<AttributeDictionary> action = Method;
action(LoadAttribute(slot));
"attributeDictionary is pointing to the object the property returns, but not the property itself." - It must be the attributeDictionary variable of the AttributeComponent class, this variable has not been changed.
attributeDictionary = LoadAttribute(slot); did not do anything. Or I do not know.
Let's do it one step at a time. You first assign the attributeDictionary that the property returned, whatever this one is, it has address 0x0011. So attributeDictionary has value 0x0011.
Now you call LoadAttribute which also returns an AttributeDictionary object, not the same as previous phase and this one has address 0x0022. So attributeDictionary has now value 0x0022, previous address is gone.
If you were to do this:
AttributeDictionary attributeDictionary = Attribute_Component.AttributeDictionary;
attributeDictionary.someVariable = someValue;
then yes you are affecting the one returned by the property. But that won't call the setter either. If you want the setter to be called, then you have to call it, there is no other way as you cannot pass a reference to a property. Just not how the compiler is built.
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Are properties variables? 1 Answer
Update variables with C# properties in customeditor 2 Answers
Combining Lists 1 Answer