2009-07-10 29 views
8

Với hỗ trợ động mới trong C# 4, có thể viết một lớp theo cách mà nếu một phương thức được gọi trên một Ví dụ và phương thức đó không có mặt, công văn được chuyển sang phương thức khác? Điều này có thể trông giống như sau:Xử lý phương thức C# không được xác định trên đối tượng động (aka respond_to/method_missing)

public class Apple : ... { 
    // ... 

    private ... MethodMissing(string name, ...) { 
    if (name == "TurnIntoOrange") { 
     // do something 
    } 
    } 
} 

dynamic d = new Apple(); 
d.TurnIntoOrange();  // Not actually defined on Apple; will pass to MethodMissing. 

Các ngôn ngữ khác sẽ gọi đây là "hỗ trợ method_missing", dưới tiêu đề chung của lập trình meta. Tôi không chắc C# gọi nó là gì. Nhưng có thể không?

Trả lời

17

Tuyệt đối. Hoặc thực hiện IDynamicMetaObjectProvider hoặc lấy từ DynamicObject cho một tuyến đường đơn giản hơn nhiều. Xem DLR documentation để biết một số ví dụ hay.

Dưới đây là một ví dụ nhanh của DynamicObject:

using System; 
using System.Dynamic; 

public class MyDynamic : DynamicObject 
{ 
    public override bool TryInvokeMember 
     (InvokeMemberBinder binder, 
     object[] args, 
     out object result) 
    { 
     Console.WriteLine("I would have invoked: {0}", 
          binder.Name); 
     result = "dummy"; 
     return true; 
    } 

    public string NormalMethod() 
    { 
     Console.WriteLine("In NormalMethod"); 
     return "normal"; 
    } 
} 

class Test 
{ 
    static void Main() 
    { 
     dynamic d = new MyDynamic(); 
     Console.WriteLine(d.HelloWorld()); 
     Console.WriteLine(d.NormalMethod()); 
    } 
} 

<plug>

Tôi có một ví dụ lớn hơn DynamicObject trong 2nd edition of C# in Depth nhưng tôi chưa thực hiện IDyamicMetaObjectProvider. Tôi sẽ làm như vậy trước khi phát hành sách, nhưng phiên bản truy cập sớm chỉ có ví dụ DynamicObject vào lúc này. Btw, nếu bạn mua nó ngày hôm nay nó là một nửa giá - sử dụng mã số twtr0711. Tôi sẽ sửa câu trả lời này sau này để loại bỏ chút :)

</plug>

+0

Wow, nhờ Jon! –

+1

Tôi ám chỉ điều này trong tiêu đề của tôi nhưng không trực tiếp yêu cầu nó trong cơ thể: Có một ghi đè tương tự tôi muốn sử dụng để bắt chước một phương thức "responds_to" không? Tôi thấy rằng tôi có thể kiểm tra kết quả của TryInvokeMember, nhưng điều đó có thể dẫn đến các tác dụng phụ không mong muốn. –

+0

Không, tôi không tin rằng có bất kỳ cách nào để yêu cầu một phương pháp năng động cho dù nó sẽ xử lý bất cứ điều gì - mặc dù bạn có thể gọi GetDynamicMemberNames như là một điểm khởi đầu. –

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