【问题标题】:C# Reflection: "Pointer" to a value-typeC# 反射:指向值类型的“指针”
【发布时间】:2016-01-27 07:01:51
【问题描述】:

简短说明

我想知道是否有 .NET 功能让我可以操作通过反射获得的值类型。因此,当在值类型属性上调用 PropertyInfo.getValue(...) 时,我不想获取副本,而是获取原始对象并对其进行操作。

我不允许使用不安全的指针。

详细说明

之所以出现此要求,是因为我正在实现一个允许我操作 Unity3d 场景图的 Web 服务。

场景图可能具有以下结构

  • 游戏对象 1
    • 矢量 1.2
  • 游戏对象 2
    • 结构 2.1
    • 矢量 2.2

客户端可以查询以下 URI:

获取http://.../GameObject2/StructProperty/someProperty

这很有效,因为它就像通过反射遍历层次结构一样简单,按名称(例如 Struct 或 Vector)搜索属性并在相应的 PropertyInfo 上调用 getValue,将其返回给客户端。

但是客户端也可以查询:

POST http://.../GameObject2/VectorProperty/xProperty 例如5.4 作为实体主体。然后将 Vector 的 x 属性设置为 5.4

我现在正在做的是向前遍历图形(就像使用 GET 一样),直到找到 Vector 对象。然后我在做一个递归 setValue 直到我在一个引用类型上做 setValue,例如

object2.setValue(Vector.setValue(5.4));

(为简单起见,我省略了 PropertyInfo 部分。假设它在那里)

所以我必须能够查询包含值类型和引用类型的任意对象层次结构。有没有更好的方法来做我正在做的事情?

【问题讨论】:

    标签: c# reflection unity3d


    【解决方案1】:

    因此,当在值类型属性上调用 PropertyInfo.getValue(...) 时,我不想获取副本,而是获取原始对象并对其进行操作。

    那么您需要访问该字段,而不是该属性。或者,您需要调用 getter 来检索值的副本,修改副本,然后调用 setter 来更改包含对象的状态。

    这不仅在您使用反射时是正确的 - 一般情况下也是如此。你不能这样做:

    foo.Position.X = 10;
    

    其中Position 是类型为值类型的属性。你会得到一个编译时错误。相反,你需要这样的东西:

    var position = foo.Position;
    position.X = 10;
    foo.Position = position;
    

    您可以通过反射来做到这一点 - 当然,假设有 一个 setter。

    请注意,当您在这里说“原始对象”时,对于值类型(存储在该类型的字段中,即未装箱), 没有对象。只有值,作为另一个对象的一部分的字段。

    【讨论】:

    • 谢谢。目前,我正在按照您的描述进行操作。调用 getter,操作值,然后调用 setter。只是因为我处于对象/属性的层次结构中,所以我需要递归地调用层次结构链中所有更高层对象的 setter,这非常慢。但我想我坚持这一点。
    • @Marco:听起来您有多种可变值类型。这几乎总是一个坏主意。如果您可以改用类,我建议您这样做。
    猜你喜欢
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-06
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多