c #, внутренний и отражение

Есть ли способ выполнить «внутренний» код через отражение?

Вот пример программы:

using System;
using System.Reflection;

namespace ReflectionInternalTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            // Call normally
            new TestClass();

            // Call with Reflection
            asm.CreateInstance("ReflectionInternalTest.TestClass", 
                false, 
                BindingFlags.Default | BindingFlags.CreateInstance, 
                null, 
                null, 
                null, 
                null);

            // Pause
            Console.ReadLine();
        }
    }

    class TestClass
    {
        internal TestClass()
        {
            Console.WriteLine("Test class instantiated");
        }
    }
}

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

Это невозможно или есть какое-то обходное решение, которое я могу сделать?


person cyberconte    schedule 02.05.2009    source источник


Ответы (3)


Вот пример ...

  class Program
    {
        static void Main(string[] args)
        {
            var tr = typeof(TestReflection);

            var ctr = tr.GetConstructor( 
                BindingFlags.NonPublic | 
                BindingFlags.Instance,
                null, new Type[0], null);

            var obj = ctr.Invoke(null);

            ((TestReflection)obj).DoThatThang();

            Console.ReadLine();
        }
    }

    class TestReflection
    {
        internal TestReflection( )
        {

        }

        public void DoThatThang()
        {
            Console.WriteLine("Done!") ;
        }
    }
person JP Alioto    schedule 02.05.2009
comment
Просто небольшая подсказка, вы можете использовать Types.EmptyTypes вместо new Type [0]. - person Vinicius; 08.02.2013

На основании направления Преетса на альтернативный пост:

using System;
using System.Reflection;
using System.Runtime.CompilerServices;

namespace ReflectionInternalTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly asm = Assembly.GetExecutingAssembly();

            // Call normally
            new TestClass(1234);

            // Call with Reflection
            asm.CreateInstance("ReflectionInternalTest.TestClass", 
                false, 
                BindingFlags.Default | BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.NonPublic, 
                null, 
                new Object[] {9876}, 
                null, 
                null);

            // Pause
            Console.ReadLine();
        }
    }

    class TestClass
    {
        internal TestClass(Int32 id)
        {
            Console.WriteLine("Test class instantiated with id: " + id);
        }
    }
}

Это работает. (Добавлен аргумент, подтверждающий, что это новый экземпляр).

Оказывается, мне просто нужен экземпляр и закрытые BindingFlags.

person cyberconte    schedule 02.05.2009

Используйте динамическую оболочку AccessPrivateWrapper, если вы используете C # 4.0 http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html

person amazedsaint    schedule 23.05.2010
comment
Ссылка не работает - person Jaans; 22.06.2020