如何使用反射设置值类型(例如点)的属性?
How to set properties of value types (e.g. Point) using reflection?
我们在运行时动态创建了一个新的 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
但是没有用。属性不是用值设置的。
我们错过了什么吗?
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来得到两个坐标。
问题是 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)
顺便说一句,考虑一下您是否真的需要 return 值。好像没必要。
我们在运行时动态创建了一个新的 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
但是没有用。属性不是用值设置的。 我们错过了什么吗?
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来得到两个坐标。
问题是 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)
顺便说一句,考虑一下您是否真的需要 return 值。好像没必要。