lega
lega

Reputation: 13

How to change a property getter at runtime in C#

I have a class with a property that looks like this:

public class Hmd{
    Transform HmdTransform{
        get{ device.GetTransform(); }
    }
}

device.GetTransform() gets the Transform from a driver.

Now I want to change the get method of the property at runtime, to something like:

public class Hmd{
    private Transform hmdTransform;
    Transform HmdTransform{
        get{ return hmdTransform; }
    }
}

Is there any way to do that? I would have to create a new member and change the getter. If I can't create a new member could I just change the device.GetTransform() line? I assume I would have to use Reflection.Emit?

Additional complication: All of this is in Unity, so I can only use Mono.

Upvotes: 1

Views: 2678

Answers (2)

TimChang
TimChang

Reputation: 2417

Use Func<Transrom> to replace property.

public class Hmd
{
    Transform _transform;
    Func<Transform> HmdTransform;

    public Hmd()
    {
        HmdTransform = HmdTransfromA;
    }

    public void SwapHmdTranformGetWay()
    {
        if (HmdTransform == HmdTransfromA)
        {
            HmdTransform = HmdTransfromB;
        }
    }

    private Transform HmdTransfromA()
    {
        //TODO A Solution
        return null;
    }
    private Transform HmdTransfromB()
    {
        //TODO B Solution
        return null;
    }
}

Use case:

 var hmd =new Hmd()
 var A = hmd.HmdTransform(); // Get Tranform By A Solution
 hmd.SwapHmdTranformGetWay(); // Change Get Tranform Way
 var B = hmd.HmdTransform(); // Get Tranform By B Solution

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062925

You can't rewrite properties as such - you can't monkey-patch in .NET.

Options:

  • inheritance; use TypeBuilder to create a type that subclasses Hmd and overrides the HmdTransform accessor that you would need to make virtual
  • simpler - just add an override property, so something like:

    public class Hmd{
        Transform HmdTransformOverride {get;set;}
        Transform HmdTransform{
            get{ return HmdTransformOverride ?? device.GetTransform(); }
        }
    }
    

or perhaps simpler still:

public class Hmd{
    Transform _transform;
    Transform HmdTransform{
        get { return _transform ?? device.GetTransform(); }
        set { _transform = value; }
    }
}

This allows the single property to serve both purposes; when not set (or when explicitly set to null) the default behaviour applies, but it can be given an explicit value.

Upvotes: 2

Related Questions