mercredi 27 avril 2022

Overwrite reference type without breaking references

I'm trying to write a system for loading a bunch of variables from disk at runtime. For a Unity game.

I have a wrapper class that allows floats, ints etc to be passed as references:

public class RefProperty<T>
{
    private T val;
    public T Val
    {
        get => val;
        set => val = value;
    }
    
    public RefProperty()
    {
    }
    public RefProperty(T value)
    {
        Val = value;
    }
}

I want to overwrite val with one loaded from disk without breaking references. In the following, target = source will update the value of target, but reference will no longer update when target is modified.

public class Program
{
    private RefProperty<float> source = new RefProperty<float>();
    private RefProperty<float> target = new RefProperty<float>();
    private RefProperty<float> reference = new RefProperty<float>();

    public void Run()
    {
        target.Val = 1;
        reference = target;
        Debug.Log(reference.Val); // returns 1
        
        source.Val = 5;
        target = source;
        Debug.Log(reference.Val); // returns 1
        
        ///////////////////////////////
        
        target.Val = 1;
        reference = target;
        Debug.Log(reference.Val); // returns 1
        
        source.Val = 5;
        target.Val = source.Val;
        Debug.Log(reference.Val); // returns 5
    }
}

The 2nd approach target.Val = source.Val does work. However, I am trying to avoid that because ultimately I want to iterate through the fields of a class holding loads of these with different types, and some child classes, and replace all the values without having to know the types:

public class RefPropertyChild : RefProperty<float>
{
    // float specific features
    public RefPropertyChild(float value)
    {
        Val = value;
    }
}


public class Parameters
{
    public RefProperty<bool> p1 = new RefProperty<bool>(true);
    public RefProperty<int> p2 = new RefProperty<int>(5);
    public RefPropertyChild p3 = new RefPropertyChild(6);
}


public class LoadData
{
    private Parameters sourceParams;
    private Parameters targetParams;

    void load()
    {
        foreach (FieldInfo field in typeof(Parameters).GetFields())
        {
            field.SetValue(targetParams, field.GetValue(sourceParams));
        }
    }
}

As before, this does modify the values, but breaks the references, I am assuming because it's pointing to a different memory location now? Is there any way to do this or do I have to explicitly handle each type and use the getter / setters?





Aucun commentaire:

Enregistrer un commentaire