c#、内部和反射

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/814183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:13:09  来源:igfitidea点击:

c#, Internal, and Reflection

c#reflectioninternal

提问by cyberconte

Is there a way to execute "internal" code via reflection?

有没有办法通过反射执行“内部”代码?

Here is an example program:

这是一个示例程序:

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

Creating a testclass normally works perfectly, however when i try to create an instance via reflection, I get a missingMethodException error saying it can't find the Constructor (which is what would happen if you tried calling it from outside the assembly).

创建一个测试类通常工作得很好,但是当我尝试通过反射创建一个实例时,我收到一个 missingMethodException 错误,说它找不到构造函数(如果您尝试从程序集外部调用它,就会发生这种情况)。

Is this impossible, or is there some workaround i can do?

这是不可能的,还是我可以做一些解决方法?

采纳答案by cyberconte

Based on Preets direction to an alternate post:

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

This works. (Added an argument to prove it was a new instance).

这有效。(添加了一个参数来证明它是一个新实例)。

turns out i just needed the instance and nonpublic BindingFlags.

原来我只需要实例和非公共 BindingFlags。

回答by JP Alioto

Here is an example ...

这是一个例子......

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

回答by amazedsaint

Use the AccessPrivateWrapper dynamic wrapper if you are in C# 4.0 http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html

如果您使用的是 C# 4.0 http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html,请使用 AccessPrivateWrapper 动态包装器