1

リフレクションを介して「内部」コードを実行する方法はありますか?

以下にプログラム例を示します。

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 エラーが発生します (これは、アセンブリの外部から呼び出そうとした場合に発生することです)。

これは不可能ですか、それとも私ができる回避策はありますか?

4

3 に答える 3

5

ここに例があります...

  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!") ;
        }
    }
于 2009-05-02T05:33:36.497 に答える
4

別の投稿へのプリッツの方向に基づいて:

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 だけが必要であることがわかりました。

于 2009-05-02T05:51:43.113 に答える
1

C#4.0を使用している場合は、AccessPrivateWrapper動的ラッパーを使用しますhttp://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html

于 2010-05-23T12:28:51.963 に答える