如何在C#中在运行时更改属性getter

时间:2018-01-19 10:02:33

标签: c# unity3d reflection mono reflection.emit

我有一个类,其属性如下:

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

device.GetTransform()从驱动程序获取转换。

现在我想在运行时将属性的get方法更改为:

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

有没有办法做到这一点?我必须创建一个新成员并更改getter。如果我无法创建新成员,我可以更改device.GetTransform()行吗?  我假设我必须使用Reflection.Emit?

其他复杂功能:所有这些都在Unity中,因此我只能使用Mono。

2 个答案:

答案 0 :(得分:2)

您无法重写属性 - 您无法在.NET中进行猴子补丁。

选项:

  • 遗传;使用TypeBuilder创建一个子类Hmd的类型,并覆盖您需要的HmdTransform访问者virtual
  • 更简单 - 只需添加覆盖属性,如下所示:

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

或者可能更简单:

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

这允许单一财产用于两种目的;未设置时(或显式设置为null时),默认行为适用,但可以为其指定显式值。

答案 1 :(得分:0)

使用Func<Transrom>替换属性。

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;
    }
}

用例:

 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