2012-03-10 8 views
25

Trong C#, xin vui lòng không ai biết tại sao tôi không thể làm như sau? (Đặc biệt là dòng được đánh dấu 'KHÔNG tốt!' Bên dưới)Tại sao liên kết động bị lỗi khi sử dụng giao diện thừa kế?

interface A 
{ 
    void Add(dynamic entity); 
} 

interface B : A {} 

class C : B 
{ 
    public void Add(dynamic entity) 
    { 
     System.Console.WriteLine(entity); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     B b = new C(); 
     dynamic x = 23; 
     b.Add(23);  // fine 
     b.Add((int)x); // fine 
     (b as A).Add(x); // fine 
     //b.Add(x);  // NOT fine! 
    } 
} 

tôi đã hoàn toàn không có vấn đề nếu cuộc gọi không được tự động bị ràng buộc, hoặc nếu tôi dứt khoát đúc để giao diện ở thư mục gốc của hệ thống phân cấp, nhưng cuộc gọi tự động bị ràng buộc mang lại cho tôi:

Unhandled Exception: Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: No overload for method 'Add' takes '1' arguments 
    at CallSite.Target(Closure , CallSite , B , Object) 
    at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1) 
    at Program.Main(String[] args) in C:\Users\Stuart\Documents\Visual Studio 2010\Projects\CSharp Testbed\Program.cs:line 218 
+1

Bằng cách này, cuộc gọi cuối cùng không thành công ngay cả khi không có thừa kế kim cương. –

+0

@YuriyGuts: Vì vậy, nhiều cho một ví dụ compileable tối thiểu eh? :) Ok, đơn giản hóa câu hỏi trong trường hợp đó. –

+1

+1 - Nó cũng có thể là tốt để lưu ý rằng 'b.Add ((int) x)' hoạt động. –

Trả lời

0

Có vẻ như nhiều lớp kế thừa giao diện đang thực hiện khi chuyển một loại biến động. Nó chắc chắn vấp phải ràng buộc thời gian chạy.

Tại thời điểm này nếu bạn đang tìm kiếm để có được nó để làm việc một cách giải quyết có thể là:

dynamic x = 23; 
b.Add((object)x); 

dynamic y = "Hello, World!"; 
b.Add((object)y); 

Kể từ động được coi là đối tượng của IL, vì vậy tất cả mọi thứ một cách rõ ràng đúc gõ đối tượng sẽ được điều này để làm việc cho bạn.

+0

Để mã trung gian, nhập động thực sự chỉ được xem là đối tượng kiểu. Vì vậy, đối với trường hợp này ít nhất, hãy đúc đối tượng dạng động vì hai hàm tương đương về mặt chức năng cho những gì OP đang cố gắng thực hiện. –

+3

Câu hỏi không phải là làm thế nào để làm cho nó hoạt động, câu hỏi là _why nó ​​không work_. –

+0

@oleksii: Mặc dù ban đầu tôi ngạc nhiên vì điều này, nó thực sự dường như hoạt động (ngay cả khi tôi thay đổi 'C.Add' để làm điều gì đó thú vị hơn với' thực thể'). Sự hiểu biết của tôi là các diễn viên để 'đối tượng' lực ràng buộc được thực hiện tại thời gian biên dịch, nhưng rằng trong chức năng' thực thể' vẫn còn tự động gõ. Vì vậy, đây là một cách khác để thực hiện cuộc gọi bị ràng buộc tĩnh -> trường hợp mà tôi đã nói "Tôi hoàn toàn không có vấn đề gì". Thật không may, nó vẫn không giải thích tại sao tôi có vấn đề trong trường hợp ràng buộc động. –