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