【问题标题】:How to set properties of value types (e.g. Point) using reflection?如何使用反射设置值类型(例如点)的属性?
【发布时间】:2015-12-06 19:42:58
【问题描述】:

我们在运行时动态创建了一个新的Drawing.Point,它运行良好。现在我们要在运行时设置属性“X”和“Y”。 我们试图这样做:

    Public Function SetObjectProperty(propertyName As String, value As Integer, refObj As Object)

    Dim propertyInfo As PropertyInfo = refObj.GetType().GetProperty(propertyName)

    If propertyInfo IsNot Nothing Then

        propertyInfo.SetValue(refObj, value, Nothing)
        Return refObj
    End If
    Return Nothing
End Function

但它没有用。未使用值设置属性。 我们错过了什么吗?

【问题讨论】:

  • 为什么不直接调用 pointVariable.X = 10 ?
  • 因为我们被告知要保持通用性。现在我们正在创建与阅读器从 xml 文件中获取的内容动态相关的对象。所以我们不能这样编码,因为在下一个循环中可能有另一种方法(如“颜色”)需要设置其他东西,然后是点对象的属性:/我刚刚在控制台中读到value propertyInfo 是 "Int32 X" 而不是只有 "X" 这可能是问题所在,我们该如何解决?

标签: vb.net reflection properties


【解决方案1】:

问题是System.Drawing.Point 是一个值类型。当您将此值传递给SetValue 时,它会被装箱。装箱对象上的值已更改,但原始值未更改。这是在更改值之前进行装箱的修改。您还需要ByRef 参数修饰符:

Public Function SetObjectProperty(propertyName As String, value As Integer, ByRef refObj As Object)
    Dim type = refObj.GetType()
    Dim propertyInfo As PropertyInfo = type.GetProperty(propertyName)

    If propertyInfo IsNot Nothing Then
        If type.IsValueType Then
            Dim boxedObj As ValueType = refObj
            propertyInfo.SetValue(boxedObj, 25)
            refObj = boxedObj
        Else
            propertyInfo.SetValue(refObj, value)
        End If
        Return refObj
    End If
    Return Nothing
End Function

你可以像以前一样使用它:

Dim p As Point
SetObjectProperty("X", 25, p)

顺便说一句,想想你是否真的需要返回值。好像没必要。

【讨论】:

  • 好的,谢谢!这就是我一直在寻找的。他现在正在改变我的 X 值。 ;) 谢谢!
【解决方案2】:

VALUE 必须是 Drawing.Point() 类型,而不是整数。 您可以使用类似的东西

Public Function SetObjectProperty(propertyName As String, value As Point, refObj As Object)

Dim propertyInfo As PropertyInfo = refObj.GetType().GetProperty(propertyName)

If propertyInfo IsNot Nothing Then

    propertyInfo.SetValue(refObj, value.X, Nothing)
    Return refObj
End If
Return Nothing

以上,你可以使用value.X甚至只使用value来获取两个坐标。

【讨论】:

  • 好的,谢谢,这看起来像我们需要的。但是你能解释一下 SetValue 参数吗?此时“refObj”是我们的 Drawing.Point-Object,值是一个整数。 propertyInfo 是应该像“X”一样更改的属性。我们需要在这里改变什么?我是否正确,要更改 Drawing.Point 的属性,我首先需要创建一个 Drawing.Point? :/ 有没有办法只获得一个整数值?
  • 原因是Object是Drawing-Point类型,SetValue的“Value”必须做到这一点。虽然 "X" 和 "Y" 是整数/Int32 并且虽然方法 "SetValue" 也表示整数,但您必须尊重 "refObj" 的类型 - 如果您使用 VALUE.X,您将传递一个整数片段该结构(X)。 Drawing.Point 类型的对象需要一个 Drawing-Point 结构,即使您只使用它的一个坐标(整数)。与表单中的 Position 和 Location 相同:它们需要“PositionCoordinate-Like”类型才能起作用。
  • 好吧好吧。但比我无法得到它真正的动态。因为我在 SetValue 中调用的 Drawing.Point 必须在之前声明过,这就是我们现在遇到的问题。根据我们将从 xml 中获得的内容设置属性动态。 ://
  • 嗯...我不完全理解,但我会尝试解决:您必须声明一个点类型的变量,例如:Dim Sample as Point = Nothing。在运行时,您可能会得到两个坐标为整数。如果是这样,你只需要在设置属性之前做这样的事情: Sample.X = Integer1, Sample.Y = Integer2 。是吗?
  • 感谢大卫 :) 非常感谢您的帮助。但我认为我们解决了它,就像 Nico 所说的那样,是盒装对象的问题。很抱歉抽出您的时间,感谢您的帮助:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多