So I'm writing a parser that uses an xml document to create a group of objects and fill in their properties. I want a user to be able to with attributes put a property like position.x="5" and the X position gets set to 5.
My issue is value type fields can easily be modified with the code below as I can mutate the original value, but value type properties return a copy that will have to get modified and reassigned back to the source object. Any ideas on how to handle value type properties?
Example: position is a struct of type Vector2 that is a property. MyObject.position.x = 5 will not work because calling SetValue on position will create a temporary position and set x to 5 on it. Therefore, the actual position attached to the object will not get the value of 5. If I do MyObject.position = new Vector2(5,0) I will get the position set to 5,0 since I am not attempting to mutate the position elements and instead assigning an entire value to position.
Note: I wrote some extension methods so 'GetValue' is valid on member info.
private bool SetAttributeValue(string text,object obj,MemberInfo setter)
{
BuildParseMethods();
if (!TryParseAttribute(text, setter.GetMemberType(), out object value))
return false;
setter.SetValue(obj, value);
return true;
}
private void SetChainAttribute(XmlAttribute attribute,object instance)
{
object target = instance;
MemberInfo[] bindings = null;
string[] parts = attribute.Name.Split('.');
Type type = instance.GetType();
for (int i = 0; i < parts.Length; i++)
{
bindings = type.GetMember(parts[i], BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetField | BindingFlags.SetProperty | BindingFlags.IgnoreCase);
if (bindings == null || bindings.Length == 0)
{
Debug.LogError($"Unable to find element {i} of {attribute.Name}");
return;
}
if (i < parts.Length - 1)
{
target = bindings[0].GetValue(target);
type = target != null ? target.GetType() : bindings[0].GetType();
}
}
SetAttributeValue(attribute.Value, target, bindings[0]);
}
Aucun commentaire:
Enregistrer un commentaire