使用 for each 迭代 class 属性
Using for each to iterate class properties
我有这个class
Public Class TExperience
Public ID As Integer
Public CompanyName As String
Public Country As String
Public Years As Integer
Public Months As Integer
Public JobTitle As String
Public Function Arr() As String()
Return {"ID", "CompanyName", "Country", "Years", "Months", "JobTitle"}
End Function
End Class
这就是它的工作原理
Public Function Set()
Dim D As New TExperience
D.CompanyName = "Any Data"
D.Country = "Any Data"
D.ID = "Any Data"
D.JobTitle = "Any Data"
D.Months = "Any Data"
End Function
我需要通过 "For Each....." 在 class
中交换这个
D.CompanyName = "Any Data"
D.Country = "Any Data"
D.ID = "Any Data"
D.JobTitle = "Any Data"
D.Months = "Any Data"
如何操作?
您所要求的是不可能的。如您所知,For Each
用于对可枚举列表中的每个项目执行相同的操作。对象的属性不是可枚举列表,因此 For Each
不适用于这种情况。设置多个属性值的方法和你现在做的一样。
也就是说,在为刚创建的对象设置多个属性时,您可以使用对象初始化语法,例如
Dim D As New TExperience With
{
.CompanyName = "Any Data",
.Country = "Any Data",
.ID = "Any Data",
.JobTitle = "Any Data",
.Months = "Any Data"
}
显然不是您所要求的,但仍然比您现在所做的有所改进。或者,如果对象需要所有数据,最好声明一个带有适当参数的构造函数,这样,调用必须提供数据。不过,您仍然必须在构造函数中单独设置每个 属性。
是的,这是可能的,如果...
注意: 您使用 public 字段发布了 class,例如Public CompanyName As String
。虽然使用属性通常是个好主意 - Public Property CompanyName As String
。下面的代码适用于 class 属性,但您可以用 PropertyInfo
代替 FieldInfo
。但是,建议使用属性来公开 class 值。
如果您正在寻找 yes/no 问题的答案,可以通过 for-each 设置属性吗?,答案是 是 。但是应该出现更多关于你的问题的问题。 什么时候,为什么,为什么...,等等
例如,我们有一种情况,特定类型与其他类型具有共同的属性,有时甚至派生自这些类型,我们需要转换它们。一种方法是使用 "Decorator" 模式。但这是我们为水合属性所做的工作(免责声明 - 代码是通过转换器从 c# 转换而来的,我添加了一些类似 "as type" 的东西,我不确定它是否 100% 正确)
''' Everything "S" - source, "D" - destination. "T" - type
Public Shared Function Hydrate(Of TS, TD)(source As TS, destination As TD) As TD
Dim sPI() As PropertyInfo =
source.[GetType]().GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)
Dim dPI() As PropertyInfo =
destination.[GetType]().GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)
For Each s As PropertyInfo In sPI
Dim d As PropertyInfo =
dPI.FirstOrDefault(Function(pi) pi.Name = s.Name AndAlso pi.PropertyType = s.PropertyType)
If d IsNot Nothing Then
d.SetValue(destination, s.GetValue(source, Nothing), Nothing)
End If
Next
Return destination
End Function
所以,我们开始吧。在此示例中,属性被迭代,当它们的名称和数据类型完全匹配时,它们就会被填充。但除了类似型号的水合作用外,它有什么用?我的意思是,这就是当 JSON 被反序列化等时内部发生的事情。但是在日常编程中你不会做这样的事情。
我有这个class
Public Class TExperience
Public ID As Integer
Public CompanyName As String
Public Country As String
Public Years As Integer
Public Months As Integer
Public JobTitle As String
Public Function Arr() As String()
Return {"ID", "CompanyName", "Country", "Years", "Months", "JobTitle"}
End Function
End Class
这就是它的工作原理
Public Function Set()
Dim D As New TExperience
D.CompanyName = "Any Data"
D.Country = "Any Data"
D.ID = "Any Data"
D.JobTitle = "Any Data"
D.Months = "Any Data"
End Function
我需要通过 "For Each....." 在 class
中交换这个 D.CompanyName = "Any Data"
D.Country = "Any Data"
D.ID = "Any Data"
D.JobTitle = "Any Data"
D.Months = "Any Data"
如何操作?
您所要求的是不可能的。如您所知,For Each
用于对可枚举列表中的每个项目执行相同的操作。对象的属性不是可枚举列表,因此 For Each
不适用于这种情况。设置多个属性值的方法和你现在做的一样。
也就是说,在为刚创建的对象设置多个属性时,您可以使用对象初始化语法,例如
Dim D As New TExperience With
{
.CompanyName = "Any Data",
.Country = "Any Data",
.ID = "Any Data",
.JobTitle = "Any Data",
.Months = "Any Data"
}
显然不是您所要求的,但仍然比您现在所做的有所改进。或者,如果对象需要所有数据,最好声明一个带有适当参数的构造函数,这样,调用必须提供数据。不过,您仍然必须在构造函数中单独设置每个 属性。
是的,这是可能的,如果...
注意: 您使用 public 字段发布了 class,例如Public CompanyName As String
。虽然使用属性通常是个好主意 - Public Property CompanyName As String
。下面的代码适用于 class 属性,但您可以用 PropertyInfo
代替 FieldInfo
。但是,建议使用属性来公开 class 值。
如果您正在寻找 yes/no 问题的答案,可以通过 for-each 设置属性吗?,答案是 是 。但是应该出现更多关于你的问题的问题。 什么时候,为什么,为什么...,等等
例如,我们有一种情况,特定类型与其他类型具有共同的属性,有时甚至派生自这些类型,我们需要转换它们。一种方法是使用 "Decorator" 模式。但这是我们为水合属性所做的工作(免责声明 - 代码是通过转换器从 c# 转换而来的,我添加了一些类似 "as type" 的东西,我不确定它是否 100% 正确)
''' Everything "S" - source, "D" - destination. "T" - type
Public Shared Function Hydrate(Of TS, TD)(source As TS, destination As TD) As TD
Dim sPI() As PropertyInfo =
source.[GetType]().GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)
Dim dPI() As PropertyInfo =
destination.[GetType]().GetProperties(BindingFlags.[Public] Or BindingFlags.Instance)
For Each s As PropertyInfo In sPI
Dim d As PropertyInfo =
dPI.FirstOrDefault(Function(pi) pi.Name = s.Name AndAlso pi.PropertyType = s.PropertyType)
If d IsNot Nothing Then
d.SetValue(destination, s.GetValue(source, Nothing), Nothing)
End If
Next
Return destination
End Function
所以,我们开始吧。在此示例中,属性被迭代,当它们的名称和数据类型完全匹配时,它们就会被填充。但除了类似型号的水合作用外,它有什么用?我的意思是,这就是当 JSON 被反序列化等时内部发生的事情。但是在日常编程中你不会做这样的事情。