使用匿名对象列表查询数组
Querying a Array with list of anonymous Object
在我的应用程序中,我有一个对象数组,
所有对象的类型将始终相同但未知,但我需要根据某些条件
更新数组对象的一个属性
我尝试使用反射实现如下相同的功能
Public Shared Sub FilterobjectArray(ByVal obj As Object())
Dim r = obj.Where(Function(x) CStr(x.[GetType]().GetProperty("Id")?.GetValue(x)) = "2")
For Each item In r
Dim propertyInfo As PropertyInfo = item.[GetType]().GetProperty("CompanyName")
propertyInfo.SetValue(item, Convert.ChangeType("MyCompany", propertyInfo.PropertyType), Nothing)
Next
End Sub
问题
我认为用于过滤数组的 Lambda 表达式是错误的,因为它在 x
中抛出“未设置对象引用”
我的示例实现
公司实体
Public Class Company
Public Property Id As Integer
Public Property CompanyName As String
End Class
实施
Dim comp(2) As Object
Dim comp1 = New Company With {.Id = 1, .CompanyName = "Comp1"}
Dim comp2 = New Company With {.Id = 2, .CompanyName = "Comp2"}
comp(0) = comp1
comp(1) = comp2
FilterobjectArray(comp)
有人可以提出错误的建议,也欢迎 C# 答案或语法
注意:for 循环中第一次迭代后出现错误
即在第一个“propertyInfo.SetValue”完成并且下一次迭代开始后
这是您需要的代码:
Sub Main
Dim comp(1) As Object
comp(0) = New Company With {.Id = 1, .CompanyName = "Comp1"}
comp(1) = New Company With {.Id = 2, .CompanyName = "Comp2"}
FilterobjectArray(comp)
End Sub
Public Shared Sub FilterobjectArray(ByVal obj As Object())
Dim r = obj.Where(Function(x) CStr(x.[GetType]().GetProperty("Id")?.GetValue(x)) = "2")
For Each item As Object In r
Dim propertyInfo As PropertyInfo = item.[GetType]().GetProperty("CompanyName")
propertyInfo.SetValue(item, Nothing)
Next
End Sub
您需要先将元素添加到数组中。大多数其他一切都很好,我只是简化了 SetValue
调用。
与在 C# 中声明数组大小不同,当您在 VB 中声明数组时,您指定最后一个有效索引。这意味着声明为 object(2)
的数组有 3 个槽 - 0(数组从 0 开始)、1 和 2。您放置了 2 个对象,因此第三个槽为空。
你然后 ForEach 命中第三个空位,但有一个转折:
错误 window 告诉您 x 什么都不是,x 是 LINQ 查询中使用的变量。 LINQ 查询不会在您说 Where
的行上 运行,只要您在 ForEach 中使用变量 r,它就会 运行s。所以它看起来像是第一个由于 ForEach 正在爆炸而导致错误的项目,但事实并非如此:LINQ 执行(将在第三个插槽上出现错误)被延迟,直到您枚举 LINQ 查询的结果。如果您在 Where 的末尾添加一个 .ToList()
调用,那么代码将在您的 ForEach..
之前崩溃
将另一个对象添加到索引 2 中的数组,将数组缩减为 object(1)
或提供一些保护以防止 x 为 Nothing 如果您的系统将在 运行 时间自然遇到空对象
在我的应用程序中,我有一个对象数组, 所有对象的类型将始终相同但未知,但我需要根据某些条件
更新数组对象的一个属性我尝试使用反射实现如下相同的功能
Public Shared Sub FilterobjectArray(ByVal obj As Object())
Dim r = obj.Where(Function(x) CStr(x.[GetType]().GetProperty("Id")?.GetValue(x)) = "2")
For Each item In r
Dim propertyInfo As PropertyInfo = item.[GetType]().GetProperty("CompanyName")
propertyInfo.SetValue(item, Convert.ChangeType("MyCompany", propertyInfo.PropertyType), Nothing)
Next
End Sub
问题 我认为用于过滤数组的 Lambda 表达式是错误的,因为它在 x
中抛出“未设置对象引用”我的示例实现
公司实体
Public Class Company
Public Property Id As Integer
Public Property CompanyName As String
End Class
实施
Dim comp(2) As Object
Dim comp1 = New Company With {.Id = 1, .CompanyName = "Comp1"}
Dim comp2 = New Company With {.Id = 2, .CompanyName = "Comp2"}
comp(0) = comp1
comp(1) = comp2
FilterobjectArray(comp)
有人可以提出错误的建议,也欢迎 C# 答案或语法
注意:for 循环中第一次迭代后出现错误 即在第一个“propertyInfo.SetValue”完成并且下一次迭代开始后
这是您需要的代码:
Sub Main
Dim comp(1) As Object
comp(0) = New Company With {.Id = 1, .CompanyName = "Comp1"}
comp(1) = New Company With {.Id = 2, .CompanyName = "Comp2"}
FilterobjectArray(comp)
End Sub
Public Shared Sub FilterobjectArray(ByVal obj As Object())
Dim r = obj.Where(Function(x) CStr(x.[GetType]().GetProperty("Id")?.GetValue(x)) = "2")
For Each item As Object In r
Dim propertyInfo As PropertyInfo = item.[GetType]().GetProperty("CompanyName")
propertyInfo.SetValue(item, Nothing)
Next
End Sub
您需要先将元素添加到数组中。大多数其他一切都很好,我只是简化了 SetValue
调用。
与在 C# 中声明数组大小不同,当您在 VB 中声明数组时,您指定最后一个有效索引。这意味着声明为 object(2)
的数组有 3 个槽 - 0(数组从 0 开始)、1 和 2。您放置了 2 个对象,因此第三个槽为空。
你然后 ForEach 命中第三个空位,但有一个转折:
错误 window 告诉您 x 什么都不是,x 是 LINQ 查询中使用的变量。 LINQ 查询不会在您说 Where
的行上 运行,只要您在 ForEach 中使用变量 r,它就会 运行s。所以它看起来像是第一个由于 ForEach 正在爆炸而导致错误的项目,但事实并非如此:LINQ 执行(将在第三个插槽上出现错误)被延迟,直到您枚举 LINQ 查询的结果。如果您在 Where 的末尾添加一个 .ToList()
调用,那么代码将在您的 ForEach..
将另一个对象添加到索引 2 中的数组,将数组缩减为 object(1)
或提供一些保护以防止 x 为 Nothing 如果您的系统将在 运行 时间自然遇到空对象