2009-04-29 2 views

ответ

44

Вы хотите просто вызвать конструктор без параметров, чтобы создать экземпляр? Является ли тип указанным как строка, или вы можете сделать его универсальным методом? Например:

// All error checking omitted. In particular, check the results 
// of Type.GetType, and make sure you call it with a fully qualified 
// type name, including the assembly if it's not in mscorlib or 
// the current assembly. The method has to be a public instance 
// method with no parameters. (Use BindingFlags with GetMethod 
// to change this.) 
public void Invoke(string typeName, string methodName) 
{ 
    Type type = Type.GetType(typeName); 
    object instance = Activator.CreateInstance(type); 
    MethodInfo method = type.GetMethod(methodName); 
    method.Invoke(instance, null); 
} 

или

public void Invoke<T>(string methodName) where T : new() 
{ 
    T instance = new T(); 
    MethodInfo method = typeof(T).GetMethod(methodName); 
    method.Invoke(instance, null); 
} 
7

Если предположить, что метод, который вы хотите вызвать не принимает никаких параметров:

public void InvokeMethod(Type type, string methodName) 
{ 
    object instance = Activator.CreateInstance(type); 
    MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); 

    method.Invoke(instance, null); 
} 
3

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

Успение: у вас есть типName (string), methodName (строка) и параметр (из SomeType).

public static void InvokeMethod(string typeName, string methodName, SomeType objSomeType) { 
     Type type = Type.GetType(typeName); 
     if(type==null) { 
     return; 
     } 
     object instance = Activator.CreateInstance(type); //Type must have a parameter-less contructor, or no contructor. 
     MethodInfo methodInfo =type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public); 
     if(methodInfo==null) { 
     return; 
     } 
     methodInfo.Invoke(instance, new[] { objSomeType }); 
    } 

Сообщите мне, если мои предположения ошибочны.

16

Чтобы вызвать конструктор, Activator.CreateInstance сделает трюк. У этого есть куча перегрузок, чтобы сделать вашу жизнь проще.

Если ваш конструктор parameterless:

object instance = Activator.CreateInstance(type) 

Если вам нужно parameters:

object instance = Activator.CreateInstance(type, param1, param2) 

Для вызова, метод, когда у вас есть Type объект, который вы можете вызвать GetMethod получить method, а затем Invoke (с параметрами или без них) для его вызова. Если вам это нужно, Invoke также даст вам возвращаемое значение функции, которую вы вызываете (или null, если это метод void),

Для получения более подробного примера (вставьте в консольное приложение и зайдите):

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.IO; 
using System.Reflection; 

namespace Test 
{ 
    public static class Invoker 
    { 
     public static object CreateAndInvoke(string typeName, object[] constructorArgs, string methodName, object[] methodArgs) 
     { 
      Type type = Type.GetType(typeName); 
      object instance = Activator.CreateInstance(type, constructorArgs); 

      MethodInfo method = type.GetMethod(methodName); 
      return method.Invoke(instance, methodArgs); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Default constructor, void method 
      Invoker.CreateAndInvoke("Test.Tester", null, "TestMethod", null); 

      // Constructor that takes a parameter 
      Invoker.CreateAndInvoke("Test.Tester", new[] { "constructorParam" }, "TestMethodUsingValueFromConstructorAndArgs", new object[] { "moo", false }); 

      // Constructor that takes a parameter, invokes a method with a return value 
      string result = (string)Invoker.CreateAndInvoke("Test.Tester", new object[] { "constructorValue" }, "GetContstructorValue", null); 
      Console.WriteLine("Expect [constructorValue], got:" + result); 

      Console.ReadKey(true); 
     } 
    } 

    public class Tester 
    { 
     public string _testField; 

     public Tester() 
     { 
     } 

     public Tester(string arg) 
     { 
      _testField = arg; 
     } 

     public void TestMethod() 
     { 
      Console.WriteLine("Called TestMethod"); 
     } 

     public void TestMethodWithArg(string arg) 
     { 
      Console.WriteLine("Called TestMethodWithArg: " + arg); 
     } 

     public void TestMethodUsingValueFromConstructorAndArgs(string arg, bool arg2) 
     { 
      Console.WriteLine("Called TestMethodUsingValueFromConstructorAndArg " + arg + " " + arg2 + " " + _testField); 
     } 

     public string GetContstructorValue() 
     { 
      return _testField; 
     } 
    } 
} 
+1

Tnx много. Между этими ответами только это сработало для меня ... –

+0

Что делать, если нет пространства имен, как мы предоставляем typeName – MonsterMMORPG

2

Чтобы передать параметры динамически Здесь я взял PARAMS струнные [] арг, потому что различные функции имеют различное число параметров так.

public void Invoke(string typeName,string functionName,params string[] args) 
    { 

    Type type = Type.GetType(typeName); 
    dynamic c=Activator.CreateInstance(type); 
    //args contains the parameters(only string type) 
    type.InvokeMember(functionName,BindingFlags.InvokeMethod,null,c,args); 

    } 
+2

Big +1 для использования InvokeMember для получения правильного метода и вызова всех в одном. Если OP нуждается в MethodInfo, я думаю, что для GetMethod есть переопределения, которые аналогично принимают типы параметров, чтобы получить лучший метод. –

 Смежные вопросы

  • Нет связанных вопросов^_^