C# 查询具有匿名对象列表的数组

C# 查询具有匿名对象列表的数组,c#,arrays,vb.net,linq,reflection,C#,Arrays,Vb.net,Linq,Reflection,在我的应用程序中,我有一个对象数组, 所有对象的类型将始终相同,但未知,但我需要根据某些条件更新数组对象的一个属性 我尝试使用反射实现下面的相同功能 Public Shared Sub FilterobjectArray(ByVal obj As Object()) Dim r = obj.Where(Function(x) CStr(x.[GetType]().GetProperty("Id")?.GetValue(x)) = &qu

在我的应用程序中,我有一个对象数组, 所有对象的类型将始终相同,但未知,但我需要根据某些条件更新数组对象的一个属性

我尝试使用反射实现下面的相同功能

  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中抛出“Object reference not set”

我的示例实现

    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)
公司实体

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循环中的第一次迭代后出现错误 i、 e.在第一个“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
调用。

以下是您需要的代码:

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中声明数组时,指定最后一个有效索引。这意味着声明为
对象(2)
的数组有3个插槽-0(数组从0开始)、1和2。您已经放置了2个对象,因此第三个插槽为空

然后,您将看到到达第三个空槽的ForEach,但有一个扭曲:

错误窗口告诉您x什么都不是,x是LINQ查询中使用的变量。LINQ查询不会在您所说的
where
行上运行,而是在ForEach中使用变量r后立即运行。。因此,它可能看起来是导致错误的第一项,因为ForEach正在爆炸,但事实并非如此:在枚举LINQ查询的结果之前,LINQ执行(将在第三个插槽中遇到错误)被延迟。如果在Where的末尾添加一个
.ToList()
调用,那么代码将在ForEach之前崩溃

将另一个对象添加到索引2中的数组中,将数组减少为
对象(1)
,或者如果系统在运行时自然会遇到空对象,则提供一些保护,以防止x为空

与C中声明数组大小不同,在VB中声明数组时,指定最后一个有效的索引。这意味着声明为
对象(2)
的数组有3个插槽-0(数组从0开始)、1和2。您已经放置了2个对象,因此第三个插槽为空

然后,您将看到到达第三个空槽的ForEach,但有一个扭曲:

错误窗口告诉您x什么都不是,x是LINQ查询中使用的变量。LINQ查询不会在您所说的
where
行上运行,而是在ForEach中使用变量r后立即运行。。因此,它可能看起来是导致错误的第一项,因为ForEach正在爆炸,但事实并非如此:在枚举LINQ查询的结果之前,LINQ执行(将在第三个插槽中遇到错误)被延迟。如果在Where的末尾添加一个
.ToList()
调用,那么代码将在ForEach之前崩溃


将另一个对象添加到索引2中的数组中,将数组减少为
对象(1)
,或者如果系统在运行时自然会遇到空对象,则提供一些保护,以防x为空

为什么需要使用反射?你不能简单地使用一个接口吗?因为我们不知道对象的类型,所以要根据我们使用的属性值进行过滤,你不需要将任何项添加到数组中。当您将数组传递到
FilterobjectArray
时,该数组有三个
Nothing
值。我已使用将VB代码转换为C#,并将其转换为具有3个插槽的对象数组。而且没有一个是固定的。@SreenathGanga我将重复彼得的评论。你为什么不使用界面呢?如果您知道该属性的名称,那么您已经对该类型有了足够的了解。你不需要反思。充其量,您需要过滤没有实现接口的对象,例如
OfType()
为什么需要使用反射?你不能简单地使用一个接口吗?因为我们不知道对象的类型,所以要根据我们使用的属性值进行过滤,你不需要将任何项添加到数组中。当您将数组传递到
FilterobjectArray
时,该数组有三个
Nothing
值。我已使用将VB代码转换为C#,并将其转换为具有3个插槽的对象数组。而且没有一个是固定的。@SreenathGanga我将重复彼得的评论。你为什么不使用界面呢?如果您知道该属性的名称,那么您已经对该类型有了足够的了解。你不需要反思。充其量,您需要筛选没有实现接口的对象,例如
OfType()
Thank。。但这不是问题所在,我已经完成了数组填充实际代码,但忘了添加它。抱歉,我已经更新了问题错误消息也被添加错误显示在第一个“propertyInfo.SetValue(item,Nothing)”之后谢谢..现在我在阅读peter和caiusThanks后明白了你的意思。。但这不是问题所在,我已经完成了数组填充实际代码,但忘了添加它。对不起,我已经更新了问题错误信息也被添加错误显示在第一个“propertyInfo.SetValue(item,Nothing)”之后谢谢..现在我在阅读peter和caius之后明白了你的意思