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

根据 Preets 对另一个帖子的指示:

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 回答