c #, Внутренний и Отражение
-
03-07-2019 - |
Вопрос
Есть ли способ выполнить " внутреннюю " код с помощью отражения?
Вот пример программы:
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, в котором говорится, что не удается найти конструктор (что и происходит, если вы попытаетесь вызвать его извне сборки) . р>
Это невозможно, или есть какой-то обходной путь, который я могу сделать?
Решение 2
На основании направления 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.
Другие советы
Вот пример ...
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!") ;
}
}
Используйте динамическую оболочку AccessPrivateWrapper, если вы находитесь в C # 4.0 http://amazedsaint.blogspot.com/2010/05/accessprivatewrapper-c-40-dynamic.html р>