2010-07-15 30 views
26

tôi có phương pháp:làm thế nào để tự động gọi một hàm trong C#

add(int x,int y) 

và tôi cũng có:

int a=5; 
int b=6; 
string s="add"; 

là nó có thể gọi thêm (a, b) bằng cách sử dụng chuỗi s? làm thế nào tôi có thể làm điều này trong C#?

+5

'if (s ==" thêm ") {thêm (a, b); } 'Cái này? – dtb

+0

Tôi nghĩ rằng anh ấy đang tìm kiếm một cái gì đó tương tự như javascript 'eval() 'chức năng, mà tôi không nghĩ rằng điều này tồn tại trong C#. Nhưng tôi đang háo hức chờ xem Jon Skeet cân nhắc thế nào về điều này. –

+0

có thể trùng lặp của [Tự động gọi bất kỳ hàm nào bằng cách chuyển tên hàm dưới dạng chuỗi] (http://stackoverflow.com/questions/801070/dynamically-invoking-any-function-by-passing-function-name-as-string) – kennytm

Trả lời

48

làm cách nào tôi có thể thực hiện việc này trong C#?

Sử dụng phản ánh.

add có phải là một thành viên của một số loại, như vậy (cắt ra rất nhiều chi tiết):

typeof(MyType).GetMethod("add").Invoke(null, new [] {arg1, arg2}) 

này giả add được tĩnh (lập luận khác đầu tiên Invoke là đối tượng) và tôi don' t cần thêm tham số để xác định duy nhất phương thức trong cuộc gọi GetMethod.

+1

+1. Cảm ơn, tôi chỉ sử dụng điều này trong mã của riêng tôi. Chỉ trong trường hợp bất cứ ai khác có những khó khăn tôi đã có, điều này không làm việc với các chức năng riêng tư. – David

+0

@DavidStratton Nó sẽ làm việc với các thành viên 'private': sử dụng một trong các tình trạng quá tải của [' GetMethod'] (http://msdn.microsoft.com/en-us/library/05eey4y9.aspx) có một ['BindingFlags '] (http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx) đối số với' BindingFlags.NonPublic'. – Richard

+0

Chúng ta có thể sử dụng "Func <>" thay vì Refection không? – Sreekumar

19

Sử dụng phản ánh - hãy thử phương pháp Type.GetMethod

Something như

MethodInfo addMethod = this.GetType().GetMethod("add"); 
object result = addMethod.Invoke(this, new object[] { x, y }); 

Bạn mất gõ mạnh và thời gian biên dịch kiểm tra - invoke không biết có bao nhiêu thông số phương pháp dự đoán, và những gì loại của họ và loại giá trị trả về thực tế là gì. Vì vậy, mọi thứ có thể thất bại trong thời gian chạy nếu bạn không hiểu đúng.

Nó cũng chậm hơn.

10

Bạn có thể sử dụng phản chiếu.

using System; 
using System.Reflection; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Program p = new Program(); 
      Type t = p.GetType(); 
      MethodInfo mi = t.GetMethod("add", BindingFlags.NonPublic | BindingFlags.Instance); 
      string result = mi.Invoke(p, new object[] {4, 5}).ToString(); 
      Console.WriteLine("Result = " + result); 
      Console.ReadLine(); 
     } 

     private int add(int x, int y) 
     { 
      return x + y; 
     } 
    } 
} 
11

Nếu các hàm được biết lúc biên dịch và bạn chỉ muốn tránh viết câu lệnh chuyển.

Setup:

Dictionary<string, Func<int, int, int>> functions = 
    new Dictionary<string, Func<int, int, int>>(); 

functions["add"] = this.add; 
functions["subtract"] = this.subtract; 

gọi theo:

string functionName = "add"; 
int x = 1; 
int y = 2; 

int z = functions[functionName](x, y); 
0

@ câu trả lời của Richard là rất tốt. Chỉ cần để mở rộng nó một chút:

Điều này có thể hữu ích trong một tình huống mà bạn tự động tạo ra một đối tượng không rõ loại và cần phải gọi phương pháp của nó:

var do = xs.Deserialize(new XmlTextReader(ms)); // example - XML deserialization 
do.GetType().GetMethod("myMethodName").Invoke(do, new [] {arg1, arg2}); 

becasue tại thời gian biên dịch do chỉ là một Object .

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