2011-01-17 19 views

Trả lời

13

EDIT: I nghĩ đây là một phần của ECMA 335, nhưng tôi không thể nhìn thấy nó ở đó ở bất cứ đâu.

Bạn không thể tạo như một loại đại biểu trong C#, nhưng bạn có thể trong IL:

.class public auto ansi sealed Foo 
     extends [mscorlib]System.Delegate 
{ 
    // Body as normal 
} 

Các biên dịch C# không có vấn đề sử dụng một đại biểu như:

using System; 

class Test 
{ 
    static void Main() 
    { 
     Foo f = x => Console.WriteLine(x); 
     f("hello"); 
    } 
} 

Nhưng CLR hiện khi nào cố gắng tải:

Ngoại lệ không khớp: System.TypeLoadException: Không thể tải loại 'Foo' từ lắp ráp 'Foo, Phiên bản = 0.0.0.0, Văn hóa = trung lập, PublicKeyToken = null 'vì nó không thể kế thừa trực tiếp từ lớp đại biểu. tại Test.Main()

Về cơ bản, Delegate/MulticastDelegate là một tai nạn lịch sử. Tôi tin rằng các phiên bản alpha/beta ban đầu đã tạo ra sự khác biệt, nhưng nó tỏ ra quá khó hiểu và thường không hữu ích - vì vậy bây giờ, mỗi người tham gia có nguồn gốc từ MulticastDelegate.

(Điều thú vị là đặc điểm kỹ thuật # C chỉ đề cập đến MulticastDelegate một lần, trong danh sách các loại trong nước chưa được sử dụng như những hạn chế chung.)

+0

PEVerify nói gì trên cụm từ đó với 'Foo'? – leppie

+0

@leppie: Chưa thử. Hãy làm như vậy :) (Tôi chỉ chạy ildasm trên một tuyên bố "bình thường" để có được IL, sau đó doctored nó và ilasmed.) –

+0

Tôi sử dụng ilasm/ildasm cho một đại biểu thử nghiệm và nhận được kết quả mong đợi trong câu trả lời của bạn . Cảm ơn. –

1

Không, CLR không cho phép điều đó.

Tôi nhớ lại điều gì đó mà họ muốn hiển thị trực tiếp Delegate, nhưng điều đó không bao giờ cần thiết.

2

Không, không có, vì tất cả các đại biểu phải tự nhiên có thể là Delegate.Combine ed. Ủy quyền là có đơn giản để bọc các chức năng không multicast vào một lớp cơ sở.

+0

Ngay cả khi mọi đại biểu có một con trỏ phương pháp và đích, Delegate.Combine có thể được thực hiện tốt: chỉ cần tạo một đối tượng có hai trường đại biểu thích hợp, chạy theo tuần tự. Việc sử dụng MulticastDelegates có thể mang lại lợi thế về hiệu suất trong các tình huống mà các đại biểu có số lượng đại biểu phụ thường xuyên chạy, nhưng hiếm khi liên quan đến Kết hợp và Xoá, nhưng tôi sẽ ngạc nhiên nếu nó mang lại hiệu suất tốt hơn trong các tình huống điển hình hơn. Cá nhân, tôi ước rằng có một loại "danh sách sự kiện" có thể thay đổi, có lẽ là một cấu trúc với một trường duy nhất ... – supercat

+0

... của kiểu Object, có thể giữ một giá trị rỗng, một đại biểu đơn lẻ hoặc một mảng đại biểu và bao gồm một phương thức để gọi trường đó là thích hợp cũng như thực hiện các thao tác Thêm và Loại bỏ an toàn theo luồng (bằng cách sử dụng Khóa liên động.CompareExchange); các phương thức gọi sẽ cung cấp một lựa chọn dừng tại ngoại lệ đầu tiên, hoặc cho phép tất cả các trình xử lý chạy và ném một BundledException với một danh sách tất cả các ngoại lệ đã xảy ra trong khi chạy chúng. Có danh sách sự kiện giữ tham chiếu đại biểu, thay vì danh sách các phương thức và mục tiêu sẽ loại bỏ quirks trong phương pháp hiện có. – supercat

2

System.MuticastDelegate có nguồn gốc từ System.Delegate. Mỗi cấp trong phân cấp đại biểu cung cấp một tập hợp các dịch vụ khác nhau. System.Delegate là một thùng chứa dữ liệu cho phương thức để gọi trên một đối tượng cụ thể. Với System.MulticastDelegate có khả năng bổ sung không chỉ gọi một phương thức trên một đối tượng duy nhất, mà còn trên một bộ sưu tập các đối tượng. Điều này cho phép nhiều người đăng ký tham dự một sự kiện.

Không chắc chắn, tôi đã trả lời câu hỏi của bạn.

+2

Trong khi đó âm thanh thích hợp, nó không giải thích tại sao GetInvocationList (rõ ràng về cách gọi * nhiều * phương pháp) là một phần của đại biểu, và không MulticastDelegate ... –

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