2012-01-04 50 views
8

Đồng nghiệp của tôi và tôi bắt gặp vấn đề này khi xem xét danh sách yêu cầu của một đại biểu. Nếu bạn tạo một sự kiện trong lớp X, thì bạn có thể truy cập các phương thức công khai của sự kiện tốt từ bên trong lớp đó. Nhưng (và hãy bỏ qua những thứ như tại sao bạn có quyền truy cập công cộng vào các thành viên lớp học, đây không phải là những gì chúng tôi đang hỏi!), Nếu chúng ta có lớp Y instantiating X và truy cập sự kiện trong X, nó không thể gọi bất kỳ phương thức công khai nào như GetInvocationList() của sự kiện. Chúng tôi muốn biết cách làm việc này. Dưới đây là mẫu mã (đọc nhận xét để xem ý nghĩa của chúng tôi):Làm cách nào để các phương thức công khai chỉ hiển thị trong lớp và lớp sở hữu đối tượng trong C#?

public class X 
    { 
     public delegate void TestMethod(); 

     public event TestMethod testMethod; 

     private void rubbish() 
     { 
      // can access testMethod.GetInvocationList() fine here 
      testMethod.GetInvocationList(); 
     } 
    } 

    public class Y 
    { 
     public Y() 
     { 
      X x = new X(); 
      x.testMethod += this.test; 

      // here it says testMethod can only appear on the left hand side of += or -= 
      // why is this? (i.e. the below line is invalid) 
      x.testMethod.GetInvocationList(); 
     } 

     public void test() 
     { 
     } 
    } 

Vì tò mò bạn đạt được điều này như thế nào và lý do để có tính năng này là gì?

Nhiều Cảm ơn Amit

+0

Bạn có hỏi "làm cách nào tôi có thể thực hiện điều tương tự cho lớp của riêng mình" hay "tại sao sự kiện được thiết kế theo cách đó"? – ken2k

+0

@ ken2k: Tôi nghĩ cả hai. – Maheep

+0

Xóa ** sự kiện ** từ khóa. – adatapost

Trả lời

9

Đó là những gì từ khóa event làm; nó là một công cụ sửa đổi hạn chế các hoạt động khác ngoài đăng ký cho lớp sở hữu. Nếu bạn xóa từ khóa event, bạn sẽ kết thúc với một đại biểu đơn giản mà khách hàng bên ngoài lớp có thể gọi, ví dụ: phương pháp GetInvocationList() trên.

Trong một số blog post, chúng so sánh mã IL được tạo cho một đại biểu đơn giản và sự kiện và nó được xử lý chính xác như nhau. Từ khóa event là một công cụ sửa đổi thời gian biên dịch hạn chế quyền truy cập vào các phương thức của đại biểu. (Nó cũng cho phép sử dụng trong giao diện). Tất cả các chi tiết đều có trong bài đăng trên blog.

+0

+1 bài đăng trên blog thú vị. –

+0

Cảm ơn Anders! Tôi sẽ đọc blog và quay trở lại với bất kỳ câu hỏi nào khác (ví dụ: đây là điều chúng tôi có thể làm cho các phương pháp của riêng mình hoặc có một số ma thuật xảy ra khi từ khóa sự kiện xuất hiện?) – user555265

+1

@ user555265 Nó sẽ được đưa vào trình biên dịch , nhưng có thể có một số niềm vui sau xử lý mà bạn có thể làm để có được những điều xảy ra trong thời gian chạy. Mã ở đây cho phép mọi người đặt các ràng buộc trên các enums và các đại biểu, không phải cùng một nhiệm vụ nhưng có thể là cùng một giải pháp, vì vậy có thể đáng xem lại: http://code.google.com/p/unconstrained-melody/ –

0

afaik đó là khi chỉ sử dụng các sự kiện, nếu bạn loại bỏ các "sự kiện" trong dòng bạn có thể sử dụng phương pháp tốt

1

Tôi đã tìm thấy một số thông tin về điều này - quyền truy cập này bên ngoài lớp khai báo rất hạn chế - dưới đây là từ trang MSDN (Events tutorial).

Gọi một sự kiện chỉ có thể được thực hiện từ bên trong lớp đã khai báo sự kiện. Hooking lên đến một sự kiện từ bên ngoài lớp tuyên bố nó, một sự kiện trông giống như một trường, nhưng truy cập vào trường đó là rất hạn chế. Những điều duy nhất có thể thực hiện là:

Soạn một đại biểu mới vào trường đó.

Xóa đại biểu khỏi trường (có thể là tổng hợp).

Điều này được thực hiện với toán tử + = và - =. Để bắt đầu nhận sự kiện lời gọi, mã máy khách đầu tiên tạo đại biểu của loại sự kiện đề cập đến phương thức cần được gọi từ sự kiện. Sau đó, nó sẽ gán đại biểu đó cho bất kỳ đại biểu nào khác mà sự kiện có thể được kết nối với việc sử dụng + =.

Thông tin khác có sẵn tại liên kết.

0

Hãy suy nghĩ của các đại biểu riêng rẽ với các sự kiện

hmmm ... Tôi sẽ phải mất một WAG đây.

Đặt khai báo ủy nhiệm của bạn trong không gian tên của bạn, bên ngoài bất kỳ lớp nào.

  • Trong lớp X, tạo một thể hiện của ủy nhiệm (không bao giờ quan tâm sự kiện) và đăng ký "xử lý:" (tôi sử dụng thuật ngữ loosly) như mong muốn.

  • Tạo phương thức hoặc thuộc tính công khai để lớp Y có thể nhận (tham chiếu ) đại biểu và do đó là danh sách yêu cầu.

  • Bây giờ bạn có thể làm bất cứ điều gì bạn muốn trong Class Y. Bạn thậm chí có thể tạo sự kiện "mirror" trong Class Y, sử dụng danh sách yêu cầu ủy nhiệm của Class X.

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