Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Доступ к приватному члену класса, Доступ к приватному члену класса 
:(
    Опции темы
constant
Дата 11.7.2014, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 22.7.2011

Репутация: нет
Всего: нет



Хочу я иметь доступ к приватному члену класса. Зачем это надо - за рамками данной темы и не обсуждается.
Вот упрощенный код класса:


Код

 class MyPrivateClass
    {
        public  MyPrivateClass()
        {
            m_Params.Add(new Param (1,2));            
        }
 
        private List<Param> m_Params = new List<Param>();
 
        private struct Param
        {
            public int m_A;
            public int m_B;
 
            public Param(int a, int b)
            { m_A = a; m_B = b; }
        }
    }



Хочу я значит получить доступ к списку m_Params.

Пробовал это сделать через Reflection вот так: 
Код

CollapsedWrap disabledLine numbers off
 MyPrivateClass MPCInstance =  new MyPrivateClass();
 object objVar = typeof(MyPrivateClass).GetField("m_Params", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(MPCInstance);



В этом случае да, получаю я переменную типа object и даже элементы списка вижу в отладчике.
Но вот вопрос, как это использовать дальше в программе ? Т.е. как элементы списка типа objVar[i], например.
Как преобразовать к нужному типу не знаю.
Или может быть как-то по-другому к такому приватному члену класса можно доступ поиметь ?
PM MAIL   Вверх
baldina
Дата 11.7.2014, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: нет
Всего: 101



вы получили FieldInfo, у него есть GetValueDirect() и SetValueDirect()
PM MAIL   Вверх
constant
Дата 11.7.2014, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 22.7.2011

Репутация: нет
Всего: нет



Цитата(baldina @ 11.7.2014,  11:49)
вы получили FieldInfo, у него есть GetValueDirect() и SetValueDirect()

Спасибо огромное за ответ ! Не могли бы вы мне, тупому, привести код, в котором показано  как конкретно в моем случае вытащить значение с помощью GetValueDirect(). Пока не могу понять.
PM MAIL   Вверх
baldina
Дата 11.7.2014, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: нет
Всего: 101



Код

object objVar = typeof(MyPrivateClass).GetField("m_Params", BindingFlags.NonPublic | BindingFlags.Instance).GetValueDirect(MPCInstance);


Это сообщение отредактировал(а) baldina - 11.7.2014, 13:23
PM MAIL   Вверх
constant
Дата 11.7.2014, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 22.7.2011

Репутация: нет
Всего: нет



Цитата(baldina @ 11.7.2014,  13:22)
Код

object objVar = typeof(MyPrivateClass).GetField("m_Params", BindingFlags.NonPublic | BindingFlags.Instance).GetValueDirect(MPCInstance);

Хорошо. Вопрос теперь, как мне использовать эту переменную типа object.
Ведь вот так делать нельзя:

Код

int t = objVar[0].m_A;



Как мне получить доступ к элементам списка ?
PM MAIL   Вверх
baldina
Дата 11.7.2014, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: нет
Всего: 101



constant, понятно в чем проблема. не нужен тут GetValueDirect, а нужно отрефлексировать всю работу с objVar, тем более что Param - закрытый тип
будет что-то типа

Код

            object objVar = typeof(MyPrivateClass).GetField("m_Params", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(MPCInstance);
            MethodInfo methodInfo = objVar.GetType().GetMethod("Add");
            Type[] constructorParameterTypes = { typeof(int), typeof(int) };
            Type paramType = typeof(MyPrivateClass).GetNestedType("Param", BindingFlags.NonPublic);
            ConstructorInfo c = paramType.GetConstructor(constructorParameterTypes);
            object[] constructorParameters = { 3, 4 };
            object[] methodParameters = { c.Invoke(constructorParameters) };
            methodInfo.Invoke(objVar, methodParameters);



Добавлено @ 14:31
это всего лишь вызов метода Add(new Param(3,4))

Добавлено @ 14:37
если бы struct Param был public, было бы достаточно
Код

            List<MyPrivateClass.Param> list = (List<MyPrivateClass.Param>)objVar;
            list.Add(new MyPrivateClass.Param(3, 4));



Это сообщение отредактировал(а) baldina - 11.7.2014, 14:38
PM MAIL   Вверх
constant
Дата 11.7.2014, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 22.7.2011

Репутация: нет
Всего: нет



Преогромнейшее спасибо. Отлично, теперь добавление работает. 
Вот только с ЧТЕНИЕМ проблема. Как считывать элементы Param из списка, и использовать их значение. Как ни пытаюсь, на выходе получается переменная типа object, которая не приводится к необходимым типам, и использовать ее в программе нельзя. Помогите пожалуйста !
PM MAIL   Вверх
baldina
Дата 11.7.2014, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: нет
Всего: 101



Код

            // objVar - List<Param>
            object[] methodParameters = { 0 };
            MethodInfo methodInfo = objVar.GetType().GetProperty("Item").GetGetMethod();
            // param0  - objVar[0] of Param type
            object param0 = methodInfo.Invoke(objVar, methodParameters);
            int m_A = (int)paramType.GetField("m_A", BindingFlags.Public | BindingFlags.Instance).GetValue(param0);
            int m_B = (int)paramType.GetField("m_B", BindingFlags.Public | BindingFlags.Instance).GetValue(param0);


PM MAIL   Вверх
constant
Дата 12.7.2014, 06:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 22.7.2011

Репутация: нет
Всего: нет



И еще раз преогроменнейшее спасибо, теперь проблема полностью решена. Вы офигенный программист,  baldina.
Очень жалко, что, пока не могу поставить Вам плюс из-за недостаточного количества постов у меня.
PM MAIL   Вверх
baldina
Дата 13.7.2014, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: нет
Всего: 101



я лишь прочитал мануал по reflection, и только...  smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0498 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.