2012-06-14 32 views
6

Tôi chắc chắn câu hỏi này đã được trả lời ở đâu đó nhưng tôi gặp phải các vấn đề lớn khi tìm kết hợp từ khóa phù hợp để tìm kiếm.Phương pháp thực thi trên động

Tôi tò mò muốn biết nếu nó có thể làm điều gì đó như thế này:

dynamic someObj = new SomeObject(); 

var methodName = "someMethodName"; 

// execute methodName on someObj 

tôi về cơ bản muốn biết nếu nó có thể thực thi một phương thức trên một đối tượng năng động sử dụng một biến mà các cửa hàng tên phương pháp.

+0

'đối tượng' là tên của bí danh C# cho lớp' System.Object'; bạn nên đổi tên nó thành 'obj'. – dasblinkenlight

+0

Tại sao bạn lại làm điều đó? Bạn sẽ phải sử dụng sự phản chiếu vani để tìm ra phương thức có tên đó. Không có điểm trong việc sử dụng năng động nếu bạn định làm điều đó. –

+4

Không, động là một yêu cầu ở đây. Tôi đang sử dụng SignalR và họ phơi bày một đối tượng năng động đại diện cho các kết nối máy khách hiện tại của bạn. Trên đối tượng đó, bạn có thể gọi các phương thức tùy ý ánh xạ tới các điểm cuối JavaScript được đặt trước. Tôi đang cố gắng đóng gói logic này trong một lớp cơ sở vì vậy tôi không tương tác rõ ràng với kiến ​​trúc Hub để thêm mức trừu tượng giữa mã của tôi và mã bên thứ ba – devshorts

Trả lời

7

Bạn có thể làm điều đó trên bất kỳ đối tượng nào, không nhất thiết phải là dynamic một đối tượng sử dụng reflection.

object obj = new SomeObject(); 
var meth = obj.GetType().GetMethod("someMethodName"); 
meth.Invoke(obj, new object[0]); // assuming a no-arg method 

Khi bạn sử dụng dynamic, bạn có thể sử dụng bất kỳ định danh cho một tên phương pháp, và trình biên dịch sẽ không phàn nàn:

dynamic obj = MakeSomeObject(); 
obj.someMethodName(); // Compiler takes it fine, even if MakeSomeObject returns an object that does not declare someMethodName() 
+1

+1, đáng ngạc nhiên rằng GetType() hoạt động trên một đối tượng động, nhưng bạn đã không liệt kê nó theo cách đó trong giải pháp của bạn – Milimetric

+1

@Milimetric: Không có thứ gì như là một "đối tượng động". Biến 'dynamic' giữ các đối tượng thông thường. Điều này sẽ không hoạt động với 'IDynamicMetaObject'. – SLaks

+0

Tôi có nghĩa là một đối tượng được gõ với 'dynamic' như trái ngược với một đối tượng được gõ với' var' hoặc 'DansAwesomeClass' – Milimetric

2

Vâng, bạn thực sự không cần "someMethodName" trong dấu ngoặc kép. Bạn chỉ cần làm điều này (danh sách chương trình đầy đủ):

class Program 
{ 
    static void Main(string[] args) 
    { 
     dynamic obj = new SomeObject(); 
     obj.someMethodName("hello"); 
    } 
} 

public class SomeObject 
{ 
    public void someMethodName(string message) 
    { 
     Console.WriteLine(message); 
    } 
} 

Trong trường hợp tên phương pháp của bạn đến từ một số nơi ác như javascript hoặc một cái gì đó, sau đó bạn có thể làm điều này:

class Program 
{ 
    static void Main(string[] args) 
    { 
     dynamic obj = new SomeObject(); 
     var meth = obj.GetType().GetMethod("someMethodName"); 
     meth.Invoke(obj, new object[1]{"hello"}); 
    } 
} 

public class SomeObject 
{ 
    public void someMethodName(string message) 
    { 
     Console.WriteLine(message); 
    } 
} 
+0

Cảm ơn, câu hỏi đến từ JavaScript. Tôi đang cố gắng để đóng gói cơ chế SignalR đó là làm thế nào vấn đề này trình bày chính nó – devshorts

+1

mát mẻ :) cũng là điều đáng ngạc nhiên là bạn có thể gọi GetType() trên một đối tượng năng động. Nhưng trong trường hợp này, tôi nghĩ rằng câu trả lời bạn chấp nhận là tốt hơn bởi vì bạn chỉ sử dụng một System.Object chung chung cũ như trái ngược với năng động mà có thể không phải là nhẹ. Oh, và năng động là khó khăn hơn để gỡ lỗi - Tôi đã quản lý để sụp đổ Visual Studio một vài lần trong khi thêm động lực để xem – Milimetric

1

Dựa trên ý kiến ​​của bạn, yêu cầu là có thể gọi các chức năng của proxy máy khách động SignalR bằng cách sử dụng một chuỗi. Cố gắng sử dụng sự phản chiếu để làm điều này, tức là: .GetType().GetMethod(functionName) không hoạt động, vì nó sẽ không cho bất kỳ đối tượng động nào.

Tuy nhiên, phương pháp này có thể được thực hiện bằng phương pháp Invoke của đối tượng động.

var functionName = "alertAllUsers"; 
var message = "Hello!"; 
var groupID = "1"; 

var connection = GlobalHost.ConnectionManager.GetHubContext<SomeHub>(); 
connection.Clients.Group(groupID).Invoke(functionName, message); 
Các vấn đề liên quan