我想将数组的值复制到Structure中。
示例:
' The Array
Dim Columns(2) As String
' The Structure
Private Structure Fields
Public FName As String
Public LName As String
Public Email As String
End Structure
' I would like to map it like so:
Fields.FName = Columns(0)
Fields.LName = Columns(1)
Fields.Email = Columns(2)
显然我可以编写一个函数,如果它很简单,但实际上有超过25列,编写一个可以映射它的函数很难。
有没有办法做到这一点?
答案 0 :(得分:1)
在所有情况下都没有简单的方法可行。你抱怨的是太多的努力是保证它在所有情况下都能发挥作用的唯一方法。
也就是说,如果你能保证数组中元素的数量与结构/类中的属性/字段数相匹配,并且它们的顺序和类型相同,那么你可以使用循环,例如
Private Function Map(source As Object()) As SomeType
Dim result As New SomeType
Dim resultType = result.GetType()
Dim fields = resultType.GetFields()
For i = 0 To source.GetUpperBound(0)
fields(i).SetValue(result, source(i))
Next
Return result
End Function
编辑:
我提供的代码按原样工作,如果SomeType是一个类,但是,因为我第一次错过了,而不是一个结构。原因是结构是值类型,因此原始对象的副本被发送到SetValue
,因此字段值永远不会在该原始对象上设置。理论上,为了防止创建副本,您应该能够简单地将值包装起来,即将其包装在Object
引用中:
Private Function Map(source As Object()) As SomeType
Dim result As Object = New SomeType
Dim resultType = result.GetType()
Dim fields = resultType.GetFields()
For i = 0 To source.GetUpperBound(0)
fields(i).SetValue(result, source(i))
Next
Return DirectCast(result, SomeType)
End Function
事实证明,VB编译器对待它的方式与C#编译器处理等效的C#代码略有不同,但它仍然无法正常工作。这是因为,在VB中,盒装值在传递给方法之前会被取消装箱,因此仍然会创建一个副本。为了使其在VB中运行,您需要使用ValueType
引用而不是Object
:
Private Function Map(source As Object()) As SomeType
Dim result As ValueType = New SomeType
Dim resultType = result.GetType()
Dim fields = resultType.GetFields()
For i = 0 To source.GetUpperBound(0)
fields(i).SetValue(result, source(i))
Next
Return DirectCast(result, SomeType)
End Function