Отражение - SetValue массива в классе? - PullRequest
3 голосов
/ 19 февраля 2009

Хорошо, я уже некоторое время работаю над чем-то, используя рефлексию, чтобы выполнить большую часть того, что мне нужно, но я наткнулся на камень преткновения ...

Я пытаюсь использовать отражение, чтобы заполнить свойства массива дочернего свойства ... не уверен, что это понятно, поэтому, вероятно, лучше объяснить в коде:

Родительский класс:

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

Детский класс:

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

Итак, используя отражение, я пытаюсь установить значения массива дочерних объектов через родительский объект ...

Я перепробовал несколько методов ... Следующее - в значительной степени то, что у меня есть в данный момент (я добавил примеры данных, просто для простоты):

    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

Это с треском проваливается на PropItem.SetValue с ArgumentException: метод набора свойств не найден.

У кого-нибудь есть идеи?

@ Джон: -

Спасибо, я думаю, что я продвинулся немного дальше, создав отдельные дочерние объекты, а затем присвоив их массиву ... Теперь проблема заключается в попытке присвоить этот массив родительскому объекту (используя отражение).

Это не должно быть сложно, но я думаю, что проблема возникает потому, что я не обязательно знаю типы родительский / дочерний. Я использую рефлексию, чтобы определить, какой родительский / дочерний объект передается. Родитель всегда имеет только одно свойство, которое является массивом дочернего объекта. Когда я пытаюсь присвоить дочерний массив родительскому объекту, я получаю недопустимое исключение приведения, говорящее, что он не может преобразовать Object [] в.

EDIT: По сути, сейчас у меня есть:

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

ResponseObject является экземпляром родительского класса, а ResponseChildren является массивом дочернего класса.

Это не с: Объект типа 'System.Object []' нельзя преобразовать в тип 'childObject []'.

Ответы [ 2 ]

4 голосов
/ 19 февраля 2009

Во-первых, я бы избавился от части массива уравнения - я не понимаю, насколько это актуально. Попробуйте написать код, чтобы установить значения для одного дочернего элемента.

Во-вторых, кажется, что вы полагаетесь на результаты GetProperties в нужном порядке - вы не должны. Нет никакой гарантии относительно того, в каком порядке будут возвращаться свойства. Вы должны знать, какой порядок вы хотите, основываясь на строке, которую вы разбиваете, и извлекать свойства по имени .

В-третьих, я подозреваю проблема в том, что у вас есть как свойства, доступные только для чтения, так и свойства, доступные для записи. Я предлагаю вам создать короткое консольное приложение, чтобы проверить это, и записать, какие свойства вы пытаетесь установить, прежде чем устанавливать его.

Если это не поможет, пожалуйста, опубликуйте короткое, но полное консольное приложение, которое демонстрирует проблему, и я уверен, что мы сможем ее исправить.

РЕДАКТИРОВАТЬ: Хорошо, если вы сейчас застряли только на части массива, я предлагаю вам показать короткий, но полный пример , который вместо . Я подозреваю, что проблема в том, что вы создали массив неправильного типа. Вы можете использовать Array.CreateInstance для создания правильного вида массива, который должен быть действителен при установке свойства.

1 голос
/ 22 марта 2010

Доступны библиотеки, облегчающие (и ускоряющие) работу с отражением. Например, Fasterflect позволяет написать следующее:

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

При этом будет получено свойство «child» для объекта «parent». Поскольку мы ожидаем, что это будет массив, мы возьмем элемент в позиции «index» (единственный дочерний экземпляр) и установим его свойство Name в «name».

Отказ от ответственности: я участвую в указанном проекте в качестве участника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...