使用匿名对象列表查询数组

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 如果您的系统将在 运行 时间自然遇到空对象