2009-04-29 40 views

Trả lời

44

Bạn chỉ muốn gọi một hàm tạo tham số để tạo cá thể không? Loại được chỉ định là một chuỗi là tốt hay bạn có thể biến nó thành một phương thức chung không? Ví dụ:

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

hoặc

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

Giả sử rằng các phương pháp mà bạn muốn gọi không mất bất kỳ thông số:

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

Tôi nghĩ vấn đề của bạn là ít quá chung chung ở đây, tôi đang cung cấp giải pháp với các giả định nhất định ở đây.

Giả sử: bạn có một typeName (string), methodName (string) và một tham số (của 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 }); 
    } 

cho tôi biết nếu giả định của tôi sai.

16

Để gọi một hàm tạo, Activator.CreateInstance sẽ thực hiện thủ thuật. Nó có một loạt các quá tải để làm cho cuộc sống của bạn dễ dàng hơn.

Nếu constructor của bạn là parameterless:

object instance = Activator.CreateInstance(type) 

Nếu bạn cần parameters:

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

Để gọi, một phương pháp, một khi bạn có đối tượng Type bạn có thể gọi GetMethod để có được những method, và sau đó Invoke (có hoặc không có tham số) để gọi nó. Nếu bạn cần, Invoke cũng sẽ cung cấp cho bạn giá trị trả lại của hàm bạn đang gọi (hoặc null nếu phương thức void của nó),

Để có mẫu chi tiết hơn một chút (dán vào ứng dụng bảng điều khiển và di chuyển):

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 rất nhiều. Giữa những câu trả lời này, chỉ có điều này làm việc cho tôi ... –

+0

nếu không có không gian tên, làm thế nào để chúng tôi cung cấp typeName – MonsterMMORPG

2

Để vượt qua các thông số động Ở đây tôi đã lấy chuỗi params [] args, bởi vì chức năng khác nhau có số lượng khác nhau của các thông số như vậy.

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 cho việc sử dụng InvokeMember để có được phương pháp đúng và gọi tất cả trong một. Nếu OP cần MethodInfo, tôi nghĩ có phần ghi đè cho GetMethod tương tự như lấy các kiểu tham số để có được phương thức tốt nhất. –

Các vấn đề liên quan