2012-01-10 24 views
14

Tôi đang sử dụng phân tích mã Resharper 5.1 nhiều một lần tôi nhận được một lời nhận xét từ resharper nhưEvent việc hủy đăng ký thông qua đại biểu vô danh

"việc hủy đăng ký tổ chức sự kiện thông qua đại biểu vô danh"

#Part of Code 

if (((bool)e.NewValue)) 
{ 
    listView.PreviewTextInput += (o,args) => 
     listView_PreviewTextInput(o,args,listView); 
} 
else 
{ 
    listView.PreviewTextInput -= (o, args) => 
     listView_PreviewTextInput(o, args, listView); 
} 

Làm thế nào tôi có thể sửa chữa hoặc tối ưu hóa điều này

Trả lời

29

Bạn có thể trích xuất lamdba thành một biến:

EventHandler func = (sender, e) => 
    listView_PreviewTextInput(sender, e, listView); 

if (((bool)e.NewValue)) 
{ 
    listView.PreviewTextInput += func; 
} 
else 
{ 
    listView.PreviewTextInput -= func; 
} 
+0

Cảm ơn nhưng 'EventHandler' phải cụ thể đúng không ?? Cuz của nó cho tôi một lỗi ... 'System.EvenTArgs không thể gán cho TextCompositonEventArgs' – Ankesh

+0

Trong trường hợp đó' listView.PreviewTextInput' không phải là 'EventHandler' nhưng có thể là' EventHandler ', nhưng không có cách nào cho tôi biết, vì bạn không thể hiện điều đó trong câu hỏi của mình. – Steven

+0

Yup .. xấu của tôi .. Cảm ơn ne cách ... :) – Ankesh

6

Cảnh báo! Accepted answer từ Steven là sai, tất cả những gì bạn làm chỉ là che giấu sự cố mà tính năng chia sẻ lại đang cảnh báo.

Mỗi lần mã nhất định được thực hiện

EventHandler func = (sender, e) => 
    listView_PreviewTextInput(sender, e, listView); 

bạn sẽ nhận được một tươi (kể từ khi bạn có thể nắm bắt khác nhau listView) thể hiện của đại biểu vô danh lưu vào func, một trường hợp mà không phải đăng ký với bất kỳ sự kiện nào, vì vậy lần lượt mã này

listView.PreviewTextInput -= func; 

sẽ không thực hiện được gì vì bạn không thể hủy đăng ký khỏi sự kiện bạn chưa đăng ký. Điều này sẽ dẫn đến lỗi tâm-boggling như xử lý sự kiện 'gọi là hai lần', rò rỉ bộ nhớ vv

Trên thực tế, Jon Skeet nói nó may work in some cases:

C# đặc điểm kỹ thuật khẳng định một cách rõ ràng (IIRC) rằng nếu bạn có hai các chức năng ẩn danh (các phương thức ẩn danh hoặc biểu thức lambda) nó có thể hoặc không thể tạo các đại biểu bình đẳng từ mã đó.

ví dụ: khi trình biên dịch không tạo ra cá thể mới mỗi lần, bạn sẽ thấy hành vi tốt đẹp.

Nhưng điều đó không đáng tin cậy và chắc chắn sẽ không hoạt động trong trường hợp được mô tả trong câu hỏi khởi động với biến bị bắt listView.

Vì vậy, đề nghị của tôi là:

Sử dụng chức năng ẩn danh như xử lý sự kiện CHỈ nếu bạn sẽ không bao giờ phải bỏ đăng ký.

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