2009-04-29 8 views

答えて

44

インスタンスを作成するために、パラメータのないコンストラクタを呼び出すだけですか?型も文字列として指定されていますか、それとも汎用メソッドにすることはできますか?

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

ここでは特定の前提を持つ解を提供しています。

仮定:typeName(文字列)、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 }); 
    } 

私の前提が間違っている場合はお知らせください。

3

私はあなたの問題はここで少し一般的すぎると思い、私は:たとえば、次のように呼び出したいメソッドは、パラメータを取らないと仮定すると

// 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); 
} 
16

コンストラクタを呼び出すには、Activator.CreateInstanceがトリックを行います。あなたの人生を楽にする過負荷がたくさんあります。

あなたのコンストラクタがparameterlessの場合:

object instance = Activator.CreateInstance(type) 

あなたがparametersが必要な場合:

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

、メソッドを呼び出すには、あなたがTypeオブジェクトを持っていたら、あなたはmethodを取得するためにGetMethodを呼び出すことができ、それを呼び出すためにInvoke(パラメータ有りまたは無し)。呼び出す関数の戻り値も返されます(空の場合はnull)

もう少し詳細なサンプル(コンソールアプリケーションに貼り付けて移動してください):

+1

Tnxたくさん。これらの答えの間に、これだけ私のために働いた... –

+0

どのような名前空間がない場合私たちはどのようにtypeNameを提供する – MonsterMMORPG

2
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; 
     } 
    } 
} 

ここ動的 にパラメータを渡すために、異なる機能が非常に異なるパラメータ数を持っているので、私は、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

大きな+1 InvokeMemberを使用して正しいメソッドを取得し、1つを呼び出す。 OPにMethodInfoが必要な場合は、GetMethodをオーバーライドして、同じようにパラメータ型を取って最適なメソッドを取得すると思います。 –