Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > .NET для новичков > использование private методов из другого класса...


Автор: newsTester 9.7.2008, 18:15
Только прошу без гнилых яблок и т.п....
Раньше писала на Java и была уверена что private метод на то и private что из других классов не виден. Теперь пришлось переходить на C# и, по идее, надо создать код обращающийся к private методам другого класса. При этом все лежит в одном Solution (кстати как это по русски будет?) и весь кодя я в принципе вижу, но менять мне его низзя.  smile 
Может это важно... класс нарушающий общее правило пространства видимости не простой, а NUnit_овский.

Автор: Freak_FB 9.7.2008, 18:24
Приватные поля на то и придуманы, чтобы их никто посторонний не изменял. Должны быть предусмотрены методы или свойства, меняющие эти поля. Не иначе.

Автор: newsTester 9.7.2008, 18:34
Цитата

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


Так я и думала  smile . Но вот один авторитетный дяденька говорит что с помощью класса Type эту схему можна нарушить... Хотя по моему это бред какой-то, но я ж толком С# не знаю - может он даже это позволяет....

Автор: PashaPash 9.7.2008, 18:52
newsTester, 
Код

class PrivateFieldsClass
{ 
    private int myPrivateField = 0;
}

class Program
{
    static void Main(string[] args)
    {
        PrivateFieldsClass myObject = new PrivateFieldsClass();
        System.Reflection.FieldInfo fieldInfo = myObject.GetType().GetField("myPrivateField", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
        fieldInfo.SetValue(myObject, 42);

    }
}

Но лучше прислушайся к Freak_FB.

Автор: newsTester 9.7.2008, 19:01
PashaPash. Видимо это и имелось ввиду  smile . А если у меня глобально класс ну... например internal? Это тоже как то обойти можно?

Автор: PashaPash 9.7.2008, 19:06
newsTester, можно, но нельзя. smile

Автор: newsTester 9.7.2008, 19:12
Цитата

можно, но нельзя


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

Автор: Partizan 9.7.2008, 19:15
newsTester, аналогично через Reflection дёргаете тип класса, а затем создаёте экземпляр с помощью Activator.CreateInstance

Автор: nikitao 9.7.2008, 20:01
newsTester,  вы уверены , что все так , как вы думаете ? smile  Все таки private на то и приват , чтобы не менять. Там должны быть Свойства , через которые вы можете получить "контрольный доступ " и полям , ну или ф-ции...


Цитата(newsTester @  9.7.2008,  19:15 Найти цитируемый пост)
Solution (кстати как это по русски будет?) 

По-русски - это солюшен , а по старо-русски - Решение.

Автор: newsTester 9.7.2008, 20:14
Цитата

вы уверены , что все так , как вы думаете ?   Все таки private на то и приват , чтобы не менять. 

Вы на 100% правы, но моя задача не использовать класс, а протестировать его работу. В том числе и работу приватной части. Ну и вот... поля и правда трогать может и не надо, а вот методы прийдется (.
Так что все из-за того что у меня задача специфическая.

Автор: newsTester 10.7.2008, 11:28
Цитата

аналогично через Reflection дёргаете тип класса

всеравно не понятно...
Цитата

Код

System.Reflection.FieldInfo fieldInfo = myObject.GetType().GetField("myPrivateField", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);


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

Автор: Partizan 10.7.2008, 14:52
newsTester, можете по имени сборки загрузить её экземпляр с помощью Assembly.Load а затем вызвать Assembly.GetTypes()...
после этого для нужного типа вызываете Activator.CreateInstance();

Автор: newsTester 2.8.2008, 00:18
c private полями разобралась, со свойствами разобралась, с классами разобралвсь, а вот с методами - никак ( вот не вижу я как запустить метод и усе... smile . 
По идее должно быть как и со свойствами... но вот как?

Автор: Partizan 2.8.2008, 00:47
Код

Type type = typeof(ИМЯ_КЛАССА_СОДЕРЖАЩЕГО_ПРИВАТНЫЙ_МЕТОД_GetDescription);
object invoker = Activator.CreateInstance(type);
MethodInfo mGetDescription = type.GetMethod("GetDescription", BindingFlags.NonPublic | BindingFlags.Instance);
object res = miGetDescription.Invoke(invoker, new object[]{});

Автор: jonie 3.8.2008, 01:38
если имеете доступ к исходным кодам, тогда сделайте класс partial, допишите какой вам нужно код и тестируйте.
например : делаете свой солюшен, куда добавляете весь исходный солюшен, и еще один файл, содержащий в себе методы доступа к классу и его тестирования. 
думаю добавить одно слово к объявлению класса удобнее, нежели плясать с рефлексией ....

Автор: newsTester 6.11.2008, 02:55
Цитата(jonie @ 3.8.2008,  01:38)
если имеете доступ к исходным кодам, тогда сделайте класс partial, допишите какой вам нужно код и тестируйте.
например : делаете свой солюшен, куда добавляете весь исходный солюшен, и еще один файл, содержащий в себе методы доступа к классу и его тестирования. 
думаю добавить одно слово к объявлению класса удобнее, нежели плясать с рефлексией ....

Цитата

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


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

Автор: jonie 7.11.2008, 10:45
http://msdn.microsoft.com/en-us/library/wa80x488(VS.80).aspx
там про partial почитайте.

Автор: Wizard_Memfis 7.11.2008, 11:11
Как я понимаю это необходимо для NUnit тестирования.
Делайте так:
Код

ClassA obj = new ClassA();
            Type type = obj.GetType();
            MethodInfo infoMethod = type.GetMethod("PrivateMethod", BindingFlags.Instance | BindingFlags.NonPublic);
            if (null == infoMethod)
            {
                throw new Exception("Cannot access PrivateMethod method!");
            }
            object[] vars = { }; // параметры метода
            Type_result result=(Type_result) infoMethod.Invoke(obj, vars);


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

Автор: Partizan 7.11.2008, 12:03
Цитата

так как сама по себе рефлексия очень медленная


+ прога, использующая reflection вряд ли успешно будет работать после обфускации =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)