2011-11-15 3 views
6

Tôi đang tự hỏi nếu tôi làm điều gì đó như thế này:C# môn thi đấu và phương pháp lớp

class A 
{ 
    public MethodA() 
    { 
    } 
    public MethodB() 
    { 
     ExternalObject.Click += this.MethodA; 
    } 
    public MethodC() 
    { 
     ExternalObject.Click -= this.MethodA; 
    } 
} 

A a = new A(); 
a.MethodB(); 
a.MethodC(); 

Đây có phải là đi làm? Bởi "công việc" tôi có nghĩa là - sẽ MethodA được hủy đăng ký từ sự kiện ExternalObject.Click?

Và các câu hỏi có liên quan khác:

Điều gì xảy ra sau khi sử dụng phương pháp thể hiện thay cho cá thể đại diện? (như trên)

Điều này có gây ra sự tạo ra tiềm ẩn của một đại biểu không?

Nhà điều hành -= thực hiện so sánh giữa các đại biểu - bằng cách tham chiếu hoặc điều gì đó phức tạp hơn xảy ra?

Trả lời

8

Có, nó sẽ hoạt động như bạn muốn.

So sánh không theo tham chiếu, nó là theo giá trị, có nghĩa là bạn có thể hủy đăng ký một đại biểu khác, miễn là nó trỏ đến cùng một phương thức trên cùng một đối tượng.

Nói cách khác, điều này sẽ chỉ làm việc tốt:

var delegate1 = new ExternalObjectClickEventHandler(MethodA); 
var delegate2 = new ExternalObjectClickEventHandler(MethodA); 
ExternalObject.Click += delegate1; 
ExternalObject.Click -= delegate2; 

phương pháp Anonymous đang khác nhau tuy nhiên, bạn không thể làm điều này:

public MethodB() 
{ 
    ExternalObject.Click +=() => { return 10; }; 
} 

public MethodC() 
{ 
    ExternalObject.Click -=() => { return 10; }; 
} 

Trong khi phương pháp chứa mã cùng, họ được coi khác nhau và do đó điều này sẽ không hoạt động, tức là, MethodC sẽ không hủy đăng ký đại biểu bạn đã thêm trong MethodB.

Để giải quyết vấn đề này, bạn phải lưu trữ các đại biểu giữa lời gọi, như thế này:

private ExternalObjectClickEventHandler _ClickEventHandler; 
public MethodB() 
{ 
    _ClickEventHandler =() => { return 10; }; 
    ExternalObject.Click += _ClickEventHandler; 
} 

public MethodC() 
{ 
    ExternalObject.Click -= _ClickEventHandler; 
} 

Nhưng mã bạn thấy, sẽ làm việc.

Đối với câu hỏi của bạn những gì xảy ra đằng sau hậu trường, đó là hai dòng mã sau đây là giống hệt nhau khi nói đến mã được tạo:

ExternalObject.Click += MethodA; 
ExternalObject.Click += new ExternalObjectClickEventHandler(MethodA); 

Các mã thứ hai là những gì được tạo ra từ đầu tiên (giả sử loại sự kiện được hiển thị.)

Cú pháp đầu tiên là (tại một số điểm) được thêm vào là "đường cú pháp" được dịch bởi trình biên dịch như thể bạn đã viết cú pháp thứ hai. Lưu ý rằng điều này chỉ xảy ra nếu được biên dịch có thể tìm ra đúng loại 100%. Tôi đã nhìn thấy một số trường hợp (mà tôi không thể nhớ ngay bây giờ), nơi bạn đã phải sử dụng cú pháp đủ điều kiện bởi vì trình biên dịch không thể tìm ra những gì bạn có nghĩa là. Đặc biệt, phương pháp quá tải và generics có thể gây nhầm lẫn nó trong lĩnh vực này.

+0

Cảm ơn bạn đã trả lời kỹ lưỡng. – kubal5003

3

Có, MethodA sẽ bị hủy đăng ký.

Về câu hỏi thứ hai, tôi không chắc chắn 100%, nhưng tôi nghĩ = this.MethodA sẽ chuyển đổi thành người được ủy quyền trong nền.

+0

+1. 'this.MethodA' sẽ được chuyển hoàn toàn sang một đại biểu. – kol