Используя Reflection получить значение поля на c# - PullRequest
1 голос
/ 27 апреля 2020

Я хочу получить значение subfield('m_fullDescriptor'), однако выдает ошибку, как показано ниже. Как я могу получить значение подполя?

Структура;

введите описание изображения здесь enter image description here Код;

 public class FieldsClass
        {
            public string fieldA;

            public FieldsClass()
            {
                fieldA = "A public field";
            }
        }


FieldsClass fieldsInst = new FieldsClass();

var specFields = con.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "pmCS").FieldType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "m_pm").FieldType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "m_fullDescriptor");

fieldsInst.fieldA= (string)specFields.GetValue(con);

Я получаю ниже Ошибка;

System.ArgumentException: 'Field 'm_fullDescriptor' defined on type 'OracleInternal.ConnectionPool.PoolManager`3[OracleInternal.ConnectionPool.OraclePoolManager,OracleInternal.ConnectionPool.OraclePool,OracleInternal.ServiceObjects.OracleConnectionImpl]' is not a field on the target object which is of type 'Oracle.ManagedDataAccess.Client.OracleConnection'.'

Ответы [ 2 ]

1 голос
/ 27 апреля 2020

Не используйте Single от Linq, чтобы найти нужное поле. Используйте метод GetField, он уже принимает точное имя поля. Также можно повторно использовать флаги.

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

Я считаю, что это должно работать, а не проверяться.

var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

var pmCS = connection.GetType().GetField("pmCS", flags).GetValue(connection);
var m_pm = pmCS.GetType().GetField("m_pm", flags).GetValue(pmCS);
var m_fullDescriptor = m_pm.GetType().GetField("m_fullDescriptor", flags).GetValue(m_pm);
0 голосов
/ 27 апреля 2020

Вы пытаетесь получить значение m_fullDescriptor, которое существует для типа OracleInternal.ConnectionPool.OraclePoolManager, но вы передаете объект (con) в GetValue, который не относится к этому типу.

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

var pmCSField = connection.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "pmCS");

var m_pmField = pmCSField.FieldType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "m_pm");

var m_fullDescriptorField = m_pmField.FieldType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).Single(pi => pi.Name == "m_fullDescriptor");

var pmCSFieldValue = pmCSField.GetValue(connection);

var m_pmFieldValue = m_pmField.GetValue(pmCSFieldValue);

var m_fullDescriptorFieldValue = m_fullDescriptorField.GetValue(m_pmFieldValue);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...