Question

Existe-t-il un moyen d'exécuter " internal " code par réflexion?

Voici un exemple de programme:

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");
        }
    }
}

La création d'une classe de test fonctionne normalement parfaitement. Cependant, lorsque j'essaie de créer une instance par réflexion, une erreur missingMethodException m'indique qu'elle ne peut pas trouver le constructeur (ce qui arriverait si vous essayiez de l'appeler de l'extérieur de l'assembly). .

Est-ce impossible ou existe-t-il une solution de contournement que je peux faire?

Était-ce utile?

La solution 2

Basé sur l'orientation de Preets vers un autre poste:

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);
        }
    }
}

Cela fonctionne. (Ajout d'un argument pour prouver que c'était une nouvelle instance).

s’avère que j’ai juste besoin de l’instance et des BindingFlags non publics.

Autres conseils

Voici un exemple ...

  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!") ;
        }
    }

Utilisez l'encapsuleur dynamique AccessPrivateWrapper si vous êtes en C # 4.0 http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top