none
Помогите с рефлексией

    Вопрос

  • есть что то похожее на этот тестовый код
    Imports System.Reflection
    
    Module Module1
        Class Person
            Public Property FirstName As String
            Public Property LastName As String
        End Class
    
        Class Employee
            Inherits Person
    
            Public Property DependentPerson As Person
        End Class
    
        Sub Main()
            Dim _e As Employee
            Dim _type As Type
            Dim _p As PropertyInfo
    
            _e = New Employee
            _e.FirstName = ""
            _e.LastName = ""
            _e.DependentPerson = New Person
    
            _type = _e.GetType()
    
            Dim _props As PropertyInfo() = _type.GetProperties()
    
            For Each _prop As PropertyInfo In _props
                Console.WriteLine(_prop.Name)
            Next
    
            _p = _type.GetProperty("FirstName")
            _p.SetValue(_e, "Имя")
            _p = _type.GetProperty("LastName")
            _p.SetValue(_e, "Фамилия")
            _p = _type.GetProperty("DependentPerson.FirstName")
            _p.SetValue(_e, "Имя")
    
            Console.ReadLine()
        End Sub
    
    End Module

    данные читаются из файла и должны устанавливать соотетствующие свойства, но в этой строке происходит ошибка
    _p = _type.GetProperty("DependentPerson.FirstName")
    System.NullReferenceException, помогите разобраться, как установить свойства объекта DependentPerson
    • Изменено SergejS 13 апреля 2017 г. 15:27
    13 апреля 2017 г. 15:25

Ответы

  • Для установки значения вы использовали SetValue, а для получения значения надо использовать GetValue:

    https://msdn.microsoft.com/en-us/library/system.componentmodel.propertydescriptor.getvalue%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396


    This posting is provided "AS IS" with no warranties, and confers no rights.

    • Помечено в качестве ответа SergejS 13 апреля 2017 г. 16:55
    13 апреля 2017 г. 16:22

Все ответы

  • А зачем вы там точку поставили? Уберите ее и все что после точки.

    This posting is provided "AS IS" with no warranties, and confers no rights.

    13 апреля 2017 г. 15:46
  • Вы наверно не заметели, что свойство DependentPerson является свойством пипа Person и мне нужно установить его свойства Firstname и Lastname.
    13 апреля 2017 г. 15:52
  • Заметил, конечно. Но отражения так не работают, для каждого уровня надо все делать по новой.

    Скажем если у вас есть что то в форме "a.b.c" то придется взять тип а, найти свойство b, взять значение b, взять его тип, найти свойство c, взять значение c.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    13 апреля 2017 г. 16:07
  • хорошо, как мне тогда получить на ссылку на свойство DependentPerson экземпляра по его имени?
    13 апреля 2017 г. 16:11
  • Для установки значения вы использовали SetValue, а для получения значения надо использовать GetValue:

    https://msdn.microsoft.com/en-us/library/system.componentmodel.propertydescriptor.getvalue%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396


    This posting is provided "AS IS" with no warranties, and confers no rights.

    • Помечено в качестве ответа SergejS 13 апреля 2017 г. 16:55
    13 апреля 2017 г. 16:22
  • мне нужно не значение, а ссыку на свойство, чтобы работать с ним дальше.
    13 апреля 2017 г. 16:28
  • Спасибо, разобрался!
    13 апреля 2017 г. 16:56
  • Значение требуется чтоб получить доступ к типу и, далее, к свойству.

    Давайте еще раз посмотрим на процедуру доступа к foo.Bar.Goo:

    1. Получить тип:

       var type = foo.GetType();

    2. Получить описание свойства:

       var barPd =  type.GetProperty("Bar");

    3. Получить значение свойства:

       var bar = barPd.GetValue(foo);

    Теперь повторяем шаги 1-3 для доступа к Goo:

    1а. Получить тип:

       var type = bar.GetType();

    2а. Получить описание свойства:

       var gooPd =  type.GetProperty("Goo");

    3а. Получить (установить) значение свойства:

       var goo = gooPd.GetValue(bar); // Или pd.SetValue(bar, newGooValue);



    This posting is provided "AS IS" with no warranties, and confers no rights.

    13 апреля 2017 г. 17:03
  • Подскажите, как динамически осуществить приведение типа

    _p.SetValue(_e, CType(<Значение>, <Type>))
    тип значения свойства получаю так _p.PropertyType, но при попытки использовать _p.PropertyType в CType получаю сообщение об ощибке: "Неизвестный тип", что нужно проделать с _p.PropertyType, чтобы его можно было использовать в функции CType?
    18 апреля 2017 г. 16:07
  • Никак, CType не работает с Type. Это просто каст, ему требуется имя типа при компиляции.

    С другой стороны это и не требуется, ведь SetValue берет object. Значение при этом уже должно быть нужного типа. Точно такое же требование и для CType. 

    Если требуется изменить тип то можно использовать Convert.ChangeType(), но его возможности ограничены.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    18 апреля 2017 г. 16:35
  • У меня значения читаются из файла и устанавливаются для экземпляра объекта, в файле не все значения того типа что и свойства экзепляра

    • Изменено SergejS 18 апреля 2017 г. 16:49
    18 апреля 2017 г. 16:43
  • В таком случае CType все равно не будет работать. Используйте Convert.ChangeType() или собственный метод который поддерживает все нужные типы. Идея очень простая:

    if (type == ...)

    {

    }

    else if (type == ...)

    {

    }

    И так далее... 


    This posting is provided "AS IS" with no warranties, and confers no rights.

    18 апреля 2017 г. 16:53
  • Если почитать описание CType() и Convert.ChangeType(), то вторым аргументом идет Type, это System.Type или что то другое? Для Convert.ChangeType(<Значение>, <Type>) метод Type.GetType("System.Nullable`1[System.Int32]") выдает подходящий тип аргумента или нет?
    18 апреля 2017 г. 17:15
  • Ну давайте почитаем описание:

    https://msdn.microsoft.com/en-us/library/4x2877xb.aspx

    CType(expression, typename)  
    typename

    Any expression that is legal within an As clause in a Dim statement, that is, the name of any data type, object, structure, class, or interface.

    Никакого Type там нет, а идет имя типа как оно используется в языке при объявляении переменных.

    Сравним с Convert.ChangeType()

    PublicSharedFunction ChangeType (
    value AsObject,
    conversionType As Type
    ) AsObject

    conversionType
    Type: System.Type
    The type of object to return.
    Тут уже реально тип.

    Для типа Int32 вызовы будут разными (VB для меня иностранный, так что не смотря на практически 1:1 перевод с C# могут быть ошибки):

    Dim foo as Int32 = CType (o, Int32)

    Dim foo as Int32 = Convert.ChangeType (o, GetType(Int32))

    Кстати, почему разработчики VB всегда выбирают самые медленные и громозкие способы, обычно с использованием строк? 

    Например:

    Type.GetType("System.Nullable`1[System.Int32]") 

    Вместо 

    GetType(Int32?) или GetType(Nullable(Of Int32))



    This posting is provided "AS IS" with no warranties, and confers no rights.

    19 апреля 2017 г. 17:33
  • я разрабатываю программу на Framework 4.0 там в CType написано Type, а вот в 4.6 там стоит название типа!!!

    Так же как в
    _p.SetValue(p1, p2, p2)
    стоит, что третий параметр необязательный, но если там не указать Nothing, то выдается ошибка, а в Framework 4.6 можно ничего не указвать, я нашел описание Type.GetType(...) и там передается имено строка Type.GetType(Int32?) или Type.GetType(Nullable(Of Int32)) - не работают!!! А вот если написать так GetType(Int32?) или GetType(Nullable(Of Int32)), то работает!
    20 апреля 2017 г. 7:19
  • CType является встроенной (inline) функцией VB. То же самое относится к GetType(). К .Net и его версиям они прямого отношения не имеют.

    Не знаю где вы нашли "Type" в CType, сейчас посмотрел все версии начиная с 2003, везде все одинаково. Не удивительно, это семейство функций (Cxxx) пришло еще из VB6 (а может и раньше).

    В то же время Type.GetType() это уже функция .Net, доступна в любых .Net языках. Конечно же варианты с передачей имен типов VB с данной функцией не работают.

    Любопытно, выходит что разработчики VB используют медленный код так как не знают ... возможностей собственно VB, например встроенных функций? 


    This posting is provided "AS IS" with no warranties, and confers no rights.

    20 апреля 2017 г. 16:52
  • А разработчики на C# все такие заносчивые мудаки или только избранные?

    20 апреля 2017 г. 17:07