Cách ưa thích để tuyên bố các sự kiện


14

Tôi khá hài lòng với sự hiểu biết của tôi về mô hình sự kiện .NET. Tôi nghĩ rằng tôi có thể hiểu nhầm một sắc thái nhỏ của hệ thống.

Khi tôi bắt đầu đưa các sự kiện vào các lớp học của mình, tôi sẽ sử dụng cách tiêu chuẩn như vậy:

public event EventHandler<MyEventArgs> MyEvent;

Điều này có nghĩa là bất cứ điều gì đăng ký vào sự kiện sẽ cần một phương thức như:

void HandleThatEvent(object sender, MyEventArgs args){...}

Điều này thật tuyệt, nhưng tôi thấy rằng tôi sẽ hiếm khi quan tâm đến người gửi, vì vậy nó đã tạo ra rất nhiều chữ ký phương thức.

Vì vậy, tôi chuyển sang khai báo các loại đại biểu của riêng tôi

public delegate void MyEventHandler(SomeClass argument);

Điều này làm giảm sự lộn xộn, nhưng để lại cho tôi một vấn đề nhỏ khi viết các trình xử lý:

eventImplmentor.MyEvent += HandleThatEvent;
.
.
.
void HandleThatEvent(/*oh, um, what arguments does it take? Intellisense isn't telling me*/)

Vì vậy, tôi sẽ phải quay lại tuyên bố của đại biểu và xem xét và sau đó quay lại và viết chúng vào, hoặc biên dịch nó và chờ đợi để được nói.

Vì vậy, bây giờ thay vào đó, tôi chỉ đang sử dụng Action, Action<T>hoặc bất kỳ mẫu nào phù hợp.

public event Action<SomeClass> MyEvent;

Để tôi có thể di chuột qua sự kiện và được cho biết những thông số mà nó mong đợi.

Câu hỏi của tôi, sau tất cả những điều đó: Có cách thực hành tốt nhất để khai báo các sự kiện trong C # không? Tôi có nên quay lại EventHandler<T>đường đi, hay được Action<T>chấp nhận?


Đừng quên đảm bảo trình xử lý được sao chép cục bộ vào nơi bạn tổ chức sự kiện, luôn muốn thực hiện việc này để đảm bảo an toàn cho chuỗi.
Snoop

Bạn có thể viết các sự kiện thông minh, trung bình và loại nạc thông minh của riêng bạn bằng mã được đóng gói nhưng bất cứ điều gì bạn xuất bản đều phải tuân theo mẫu chuẩn hoặc nó sẽ chỉ gây nhầm lẫn cho người dùng của lớp bạn (và rõ ràng cũng có một số công cụ).
Martin Maat

Câu trả lời:


8

Để xử lý sự kiện đơn giản, nội bộ, có những cách đơn giản là sử dụng Actionhoặc Action<T>, như bạn đang đề xuất. Tôi có xu hướng sử dụng mẫu tiêu chuẩn, bao gồm Người gửi, ngay cả cho các sự kiện nội bộ, bởi vì bạn không bao giờ biết khi nào bạn có thể muốn tiết lộ một lớp hoặc sự kiện và tôi sẽ không muốn bị phạt khi phải cấu trúc lại phương thức sự kiện chỉ để thực hiện nó công khai.

Tôi đồng ý với bạn rằng chữ ký xử lý sự kiện nặng hơn một chút so với các kịch bản đơn giản, nhưng nó được thiết kế tốt để xử lý di chuyển gia tăng vì các đối số sự kiện bổ sung có thể trở nên cần thiết theo thời gian. Nhìn chung, tôi sẽ gắn bó với mẫu tiêu chuẩn, đặc biệt là, như bạn đã lưu ý, bạn chỉ nhận được hỗ trợ IntelliSense phù hợp nếu bạn làm như vậy.

Để biết giá trị của nó, tôi đã dành chút thời gian cho việc này và đưa ra một mẫu xử lý sự kiện khác: Chữ ký sự kiện trong .NET - Sử dụng một 'Người gửi' được gõ mạnh?. Mục tiêu ở đây không phải là loại bỏ Người gửi, mà là làm cho nó được đánh máy mạnh mẽ TSenderthay vì gõ yếu như System.Object. Nó hoạt động rất tốt; tuy nhiên, người ta sẽ mất hỗ trợ IntelliSense khi bạn thực hiện việc này, do đó, có một sự đánh đổi đáng tiếc.

Nhìn chung, tôi sẽ gắn bó với mô hình tiêu chuẩn, nhưng thật thú vị khi nghĩ về những cách có khả năng tốt hơn để làm điều này.


Cảm ơn đã chỉ cho tôi câu hỏi SO của bạn. Nó rất thú vị. Tôi vẫn không hiểu tại sao điều quan trọng là người gửi là bắt buộc. Hầu hết thời gian tôi không quan tâm đến người gửi. Có phải nó chỉ là một số quy tắc MS tùy ý?
Matt Ellen

Không, tất nhiên bạn có thể tuyên bố các đại biểu của bạn theo cách bạn muốn. Chính sách .NET luôn bao gồm người gửi và đó không hoàn toàn là một ý tưởng tồi.
Neil

@Neil: Tôi hiểu rằng đôi khi nó sử dụng hữu ích, nhưng tôi không nhận được chính sách luôn luôn làm điều đó - đặc biệt là khi MS khuyên bạn nên thực hiện các sự kiện theo cách của họ. Một trong những điều tôi thực sự thích về các sự kiện là khả năng tách lớp. Nếu tôi bao gồm cả đối tượng, thì nó sẽ được ghép lại. Nếu đó chỉ là một điều tuân thủ CLS thì tôi có thể sống với điều đó.
Matt Ellen

Nó chỉ được ghép lại một lần nữa nếu bạn sử dụng đối tượng người gửi, nếu không, điều đó không quan trọng được coi là giá trị của người gửi vì bạn không sử dụng nó. Sự phụ thuộc chỉ tồn tại nếu bạn cần có sự phụ thuộc. Tôi thấy bạn đến từ đâu và nếu người gửi đối tượng biến mất khỏi tất cả mã từ bất kỳ máy chủ nào trên hành tinh, tôi sẽ không thức đêm.
Neil

Có, bạn có thể gửi 'null' với tư cách là người gửi nếu bạn thực sự muốn ... Nhưng, bằng cách bao gồm Người gửi, chính trình xử lý sự kiện có thể hủy đăng ký nếu muốn. Tuy nhiên, nhìn chung, tôi sẽ nói rằng việc biết nguồn gốc của sự kiện thường khá quan trọng.
Mike Rosenblum
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.