【问题标题】:How to change a property getter at runtime in C#如何在 C# 中在运行时更改属性获取器
【发布时间】:2018-01-19 10:02:33
【问题描述】:

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

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

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

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

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

有没有办法做到这一点?我将不得不创建一个新成员并更改吸气剂。如果我不能创建新成员,我可以更改device.GetTransform() 行吗? 我想我必须使用 Reflection.Emit?

额外的复杂性:所有这些都在 Unity 中,所以我只能使用 Mono。

【问题讨论】:

  • 这似乎是XY problem。你真正需要什么?为什么在编译时不能有私有字段?
  • 您可以为属性将调用的类提供Func<Transform>。这样你就可以将任何你喜欢的东西传递给它。但是,正如 Camilo 所说,这对于您在这里想要实现的目标来说可能是多余的。如果您提供更多背景信息,我们可以提出更好的解决方案。
  • 绝对是 XY 问题。您试图通过明显的肮脏黑客解决的真正问题是什么?
  • 我知道这听起来很奇怪,我可能应该从另一个角度来处理这个问题(对类提出要求,而不是事后改变它们)但是我正在构建一个回放系统,我的主要目标是对我想要记录的成员(到目前为止有效)做出尽可能少的假设。当我想将数据反馈到以动态方式获取数据的对象中时,就会出现问题。

标签: c# unity3d reflection mono reflection.emit


【解决方案1】:

你不能重写这样的属性 - 你不能在 .NET 中进行猴子补丁。

选项:

  • 继承;使用TypeBuilder 创建一个子类Hmd 并覆盖您需要创建virtualHmdTransform 访问器的类型
  • 更简单 - 只需添加一个覆盖属性,例如:

    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),则应用默认行为,但可以为其指定显式值。

【讨论】:

  • 如果可能的话,这至少回答了这个问题。无法真正找到这一点,并且对 Emit 的可能性感到困惑。谢谢!
【解决方案2】:

使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 2019-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多