Frage

Gibt es eine Möglichkeit, "interner" Code durch Reflexion auszuführen?

Hier ist ein Beispielprogramm:

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

Das Erstellen einer Testklasse funktioniert normalerweise perfekt. Wenn ich jedoch versuche, eine Instanz durch Reflexion zu erstellen, erhalte ich einen fehlenden Methodexception -Fehler, in dem er den Konstruktor nicht finden kann (was passieren würde, wenn Sie versuchen würden, ihn von außerhalb der Baugruppe anzurufen).

Ist das unmöglich oder gibt es eine Problemumgehung, die ich tun kann?

War es hilfreich?

Lösung 2

Basierend auf Preets -Richtung zu einem alternativen Beitrag:

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

Das funktioniert. (Fügte ein Argument hinzu, um zu beweisen, dass es sich um eine neue Instanz handelte).

Es stellte sich heraus, dass ich nur die Instanz und nicht öffentliche BindingFlags brauchte.

Andere Tipps

Hier ist ein Beispiel ...

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

Verwenden Sie den dynamischen Wrapper AccessPrivateWrapper, wenn Sie in C# 4.0 sind http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top