I am working on a project that requires a user to be able to modify properties of an object within a certain list of types, known at compile time.
For example, say I have a type defined by
public class A
{
public float foo;
}
To set properties without reflection at near-native speeds during runtime (which is necessary for the project), I used a C# script which enumerates through the properties using reflection to generate code that looks something like this, which is then compiled.
public void Set(A obj, string path, object value)
{
switch (path)
{
case "foo":
obj.foo = (float)value;
break;
}
}
This works fine for simple types, but for more complex types, specifically where struct properties are its members, it becomes more difficult.
public class B
{
public C foo { get; set; }
}
public struct C
{
public float bar;
}
The code generated by this system no longer works, because accessing the struct property creates a copy.
public void Set(B obj, string path, object value)
{
switch (path)
{
//...
case "foo.bar":
// Cannot modify the return value of 'C.bar' because it is not a variable
obj.foo.bar = (float)value;
break;
}
}
Now, what I can do is modify the system to create a temporary struct variable, modify the member I want to access, and set the property's value to the temp variable, like so.
public void Set(B obj, string path, object value)
{
switch (path)
{
//...
case "foo.bar":
C tmp = obj.foo;
tmp.bar = (float)value;
obj.foo = tmp;
break;
}
}
This system has several problems though. Nested struct properties would be hell to unwrap, and I would have to check every single parent property to ensure a setter method exists. This seems unnecessary and cumbersome, but I don't see any other option.
Is there a way that I can set property values for an object from a string path without runtime reflection?
Aucun commentaire:
Enregistrer un commentaire