Отражение: как вызвать метод с параметрами

Я пытаюсь вызвать метод через reflection с параметрами, и я получаю:

объект не соответствует типу цели

Если я вызываю метод без параметров, он работает нормально. На основании следующего кода, если я вызываю метод Test("TestNoParameters") , он работает нормально. Однако, если я вызываю Test("Run") , я получаю исключение. Что-то не так с моим кодом?

Моя первоначальная цель состояла в том, чтобы передать массив объектов, например public void Run(object[] options) но это не сработало, и я попробовал что-то более простое, например, строку без успеха.

 // Assembly1.dll namespace TestAssembly { public class Main { public void Run(string parameters) { // Do something... } public void TestNoParameters() { // Do something... } } } // Executing Assembly.exe public class TestReflection { public void Test(string methodName) { Assembly assembly = Assembly.LoadFile("...Assembly1.dll"); Type type = assembly.GetType("TestAssembly.Main"); if (type != null) { MethodInfo methodInfo = type.GetMethod(methodName); if (methodInfo != null) { object result = null; ParameterInfo[] parameters = methodInfo.GetParameters(); object classInstance = Activator.CreateInstance(type, null); if (parameters.Length == 0) { // This works fine result = methodInfo.Invoke(classInstance, null); } else { object[] parametersArray = new object[] { "Hello" }; // The invoke does NOT work; // it throws "Object does not match target type" result = methodInfo.Invoke(methodInfo, parametersArray); } } } } } 

Измените «methodInfo» на «classInstance», как и в вызове с нулевым массивом параметров.

  result = methodInfo.Invoke(classInstance, parametersArray); 

У вас есть ошибка прямо там

 result = methodInfo.Invoke(methodInfo, parametersArray); 

должен быть

 result = methodInfo.Invoke(classInstance, parametersArray); 

Основная ошибка здесь:

 result = methodInfo.Invoke(methodInfo, parametersArray); 

Вы вызываете метод в экземпляре MethodInfo . Вам нужно передать экземпляр типа объекта, который вы хотите вызвать.

 result = methodInfo.Invoke(classInstance, parametersArray); 

Предоставленное решение не работает для экземпляров типов, загружаемых с удаленной сборки. Чтобы сделать это, вот решение, которое работает во всех ситуациях, которое включает явное переназначение типа типа, возвращаемого вызовом CreateInstance.

Вот как мне нужно создать свой classInstance, поскольку он был расположен в удаленной сборке.

 // sample of my CreateInstance call with an explicit assembly reference object classInstance = Activator.CreateInstance(assemblyName, type.FullName); 

Однако даже с предоставленным выше ответом вы все равно получите ту же ошибку. Вот как это сделать:

 // first, create a handle instead of the actual object ObjectHandle classInstanceHandle = Activator.CreateInstance(assemblyName, type.FullName); // unwrap the real slim-shady object classInstance = classInstanceHandle.Unwrap(); // re-map the type to that of the object we retrieved type = classInstace.GetType(); 

Затем сделайте так, как другие пользователи упомянули здесь.

Я бы использовал его так, его путь короче, и он не даст никаких проблем

  dynamic result = null; if (methodInfo != null) { ParameterInfo[] parameters = methodInfo.GetParameters(); object classInstance = Activator.CreateInstance(type, null); result = methodInfo.Invoke(classInstance, parameters.Length == 0 ? null : parametersArray); } 

Я попытался работать со всеми предложенными ответами выше, но для меня ничего не работает. Поэтому я пытаюсь объяснить, что сработало для меня здесь.

Я считаю, что если вы вызываете какой-либо метод, например Main ниже или даже с одним параметром, как в вашем вопросе, вам просто нужно изменить тип параметра из string в object чтобы это работало

 class Class1 { public static void Execute(object[] str) {...} } 

Затем вы должны передать параметрArray внутри массива объектов, как показано ниже, при его вызове.

 Assembly assembly = Assembly.LoadFile("...Assembly1.dll"); Type type = assembly.GetType("TestAssembly.Main"); if (type != null) { MethodInfo mi = typeInstance.GetType().GetMethod("Execute"); ParameterInfo[] parameters = mi.GetParameters(); object classInstance = Activator.CreateInstance(typeInstance.GetType(), null); if (parameters.Length == 0) { // This works fine var result = mi.Invoke(classInstance, null); } else { object[] parametersArray = new object[] { "Hello","bye" }; var result = mi.Invoke(classInstance,new object[] { parametersArray } ); } } 

Надеюсь это поможет

  Assembly assembly = Assembly.LoadFile(@"....bin\Debug\TestCases.dll"); //get all types var testTypes = from t in assembly.GetTypes() let attributes = t.GetCustomAttributes(typeof(NUnit.Framework.TestFixtureAttribute), true) where attributes != null && attributes.Length > 0 orderby t.Name select t; foreach (var type in testTypes) { //get test method in types. var testMethods = from m in type.GetMethods() let attributes = m.GetCustomAttributes(typeof(NUnit.Framework.TestAttribute), true) where attributes != null && attributes.Length > 0 orderby m.Name select m; foreach (var method in testMethods) { MethodInfo methodInfo = type.GetMethod(method.Name); if (methodInfo != null) { object result = null; ParameterInfo[] parameters = methodInfo.GetParameters(); object classInstance = Activator.CreateInstance(type, null); if (parameters.Length == 0) { // This works fine result = methodInfo.Invoke(classInstance, null); } else { object[] parametersArray = new object[] { "Hello" }; // The invoke does NOT work; // it throws "Object does not match target type" result = methodInfo.Invoke(classInstance, parametersArray); } } } } 
  • Отметить параметры как НЕВОЗМОЖНЫЕ в C # /. NET?
  • Как передавать анонимные типы в качестве параметров?
  • Поддерживает ли Java значения параметров по умолчанию?
  • Значение, переданное с request.setAttribute (), недоступно request.getParameter ()
  • Лучшая практика передачи многих аргументов методу?
  • Существует ли разумный подход к параметрам типа «по умолчанию» в C # Generics?
  • Конфликт перегруженных методов с дополнительными параметрами
  • Почему нам нужно указывать размер столбца при передаче 2D-массива в качестве параметра?
  • Android устанавливает высоту и ширину пользовательского вида программно
  • Укажите монитор при открытии файла. (.летучая мышь)
  • Как запустить EXE-файл в PowerShell с параметрами с пробелами и кавычками
  • Давайте будем гением компьютера.