views:

1032

answers:

2

OK, I've been working on something for a while now, using reflection to accomplish a lot of what I need to do, but I've hit a bit of a stumbling block...

I'm trying to use reflection to populate the properties of an array of a child property... not sure that's clear, so it's probably best explained in code:

Parent Class:

Public Class parent
    Private _child As childObject()
    Public Property child As childObject()
        Get
            Return _child
        End Get
        Set(ByVal value As child())
            _child = value
        End Set
    End Property
End Class

Child Class:

Public Class childObject
    Private _name As String
    Public Property name As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = value
        End Set
    End Property

    Private _descr As String
    Public Property descr As String
        Get
            Return _descr
        End Get
        Set(ByVal value As String)
            _descr = value
        End Set
    End Property
End Class

So, using reflection, I'm trying to set the values of the array of child objects through the parent object...

I've tried several methods... the following is pretty much what I've got at the moment (I've added sample data just to keep things simple):

    Dim Results(1) As String

    Results(0) = "1,2"
    Results(1) = "2,3"
    Dim parent As New parent

    Dim child As childObject() = New childObject() {}
    Dim PropInfo As PropertyInfo() = child.GetType().GetProperties()
    Dim i As Integer = 0
    For Each res As String In Results 
        Dim ResultSet As String() = res.Split(",")
        ReDim child(i)

        Dim j As Integer = 0
        For Each PropItem As PropertyInfo In PropInfo
            PropItem.SetValue(child, ResultSet(j), Nothing)
            j += 1
        Next
        i += 1
    Next
    parent.child = child

This fails miserably on PropItem.SetValue with ArgumentException: Property set method not found.

Anyone have any ideas?

@Jon :-

Thanks, I think I've gotten a little further, by creating individual child objects, and then assigning them to an array... The issue is now trying to get that array assigned to the parent object (using reflection).

It shouldn't be difficult, but I think the problem comes because I don't necessarily know the parent/child types. I'm using reflection to determine which parent/child is being passed in. The parent always has only one property, which is an array of the child object. When I try assigning the child array to the parent object, I get a invalid cast exception saying it can't convert Object[] to .

EDIT: Basically, what I have now is:

Dim PropChildInfo As PropertyInfo() = ResponseObject.GetType().GetProperties()
For Each PropItem As PropertyInfo In PropChildInfo
    PropItem.SetValue(ResponseObject, ResponseChildren, Nothing)
Next

ResponseObject is an instance of the parent Class, and ResponseChildren is an array of the childObject Class.

This fails with: Object of type 'System.Object[]' cannot be converted to type 'childObject[]'.

+3  A: 

Firstly I'd get rid of the array part of the equation - I can't see how that's relevant. Try to write code to set the values for a single child.

Secondly, it seems that you're relying on the results of GetProperties being in the desired order - you shouldn't. There's no guarantee as to what order the properties will be returned in. You should know what order you want based on the string you're splitting, and fetch the properties by name.

Thirdly, I suspect the problem is that you've got some read-only properties as well as writeable ones. I suggest you whip up a short console app to check this out, logging what properties you're trying to set before you set it.

If this doesn't help, please post a short but complete console app which demonstrates the problem, and I'm sure we'll be able to fix it.

EDIT: Okay, if you're now stuck just on the array part, I suggest you show a short but complete example of that instead. I suspect the problem is that you've created an array of the wrong type. You can use Array.CreateInstance to create the right kind of array, which should be valid when you then set the property.

Jon Skeet
Question updated to say where I'm at now... thanks for the starting points.
Jaymz87
Question includes example...
Jaymz87
A: 

There are libraries available to make it easier (and faster) to work with reflection. For instance, Fasterflect allows you to write the following:

parent.Property("child").GetElement(index).SetFieldValue("Name",name);

This will retrieve the property called "child" on the object "parent". Since we expect it to be an array we'll grab the element at position "index" (a single child instance) and set its Name property to "name".

Disclaimer: I am involved in said project as a contributor.

Morten Mertner