2012-11-23 15 views
5

Tôi có lớp và ủy nhiệm sau được xác định trong mã (nhiều dòng khác bị tách ra để ngắn gọn).Không có lỗi khi chữ ký ủy quyền không khớp với

Public Delegate Sub TimerCallback(canceled As Boolean) 

Public Class Timer 
    Implements TimerManager.ITimer 

    Public Sub New(delay As Integer, callback As TimerCallback) 
     mState = TimerState.Setup 
     mCallback = callback 
     CType(TimerManager.Instance, TimerManager.ITimerManager).RegisterTimer(Me, delay) 
    End Sub 
End Class 

Khi tôi tạo ra một thể hiện mới của bộ đếm thời gian với đoạn mã sau, tôi không nhận được một lỗi biên dịch, mặc dù chữ ký của chức năng ẩn danh không khớp với chữ ký của các đại biểu (nó thiếu " bị hủy như tham số boolean "".

Dim timer As New Timer(Me.CookTime, Sub() 
             Dim cooked As FoodBase = CType(Activator.CreateInstance(SuccessfulResult), FoodBase) 
             player.GetBackpack.AddItem(cooked) 
            End Sub) 

Tôi hy vọng sẽ gặp phải lỗi biên dịch khi tạo bộ hẹn giờ theo cách này, bất kỳ ai có thể giải thích lý do tại sao lại biên dịch mà không có lỗi? Có bất kỳ tùy chọn tôi có thể thiết lập mà sẽ gây ra nó để tạo ra một lỗi biên dịch? Tôi có tùy chọn rõ ràng, tùy chọn nghiêm ngặt và tùy chọn suy ra trong thuộc tính dự án. Vì nó là, nó là quá dễ dàng để quên bao gồm các đối số bị hủy bỏ.

Trả lời

4

Đúng. Đó là tốt - trình biên dịch có thể tạo ra một phương thức vô danh biết chữ ký cần thiết, và đơn giản là không sử dụng các tham số được đưa ra. Vì vậy, phương pháp do trình biên dịch tạo sẽ có thông số - nó sẽ không sử dụng nó. Bạn có thể làm tương tự trong C# bằng cách sử dụng delegate { ... }.

+1

Không phải là điểm đánh mạnh đối số vào TimerCallback để đảm bảo rằng chữ ký phương thức khớp với nhau? Tôi có thể thấy hành vi này nếu Option Infer được đặt thành On. Nhưng bằng cách thiết lập tùy chọn Infer Off tôi mong đợi trình biên dịch sẽ không suy ra bất cứ điều gì và thực thi chữ ký. Bạn có bất kỳ giải pháp cho phần thứ hai của câu hỏi của tôi về buộc biên dịch để tạo ra một lỗi hoặc ít nhất là một cảnh báo trong tình huống này? –

3

Hiện tượng này được gọi là Relaxed Delegate Conversion và có hành vi hơi khác khi Tùy chọn nghiêm ngặt là onoff. Vui lòng theo liên kết để biết thêm chi tiết.

Đây là một tính năng của VB, cho phép mã nhỏ gọn, như thế này:

Private Sub Form1_Load() Handles MyBase.Load 

Nếu bạn không sử dụng bất kỳ đối số, tại sao khai báo tất cả? Cá nhân tôi thấy nó như một lợi ích của VB, chứ không phải là một vấn đề. Nếu bạn cố gắng thực hiện tương tự trong C#, bạn nhận được lỗi biên dịch như sau:

Không quá tải cho 'Form1_Load' khớp với đại biểu 'System.EventHandler'.

+0

Đối số không được sử dụng trong/this/example, nhưng nó có thể được sử dụng ở những nơi khác. Mã Bộ hẹn giờ của tôi là một phần của thư viện mà những người khác có thể sử dụng trong các dự án của họ. Nếu những người dùng không nhận thức được chữ ký cho TimerCallback họ có thể bỏ bê để bao gồm nó, hoặc thậm chí biết về khả năng hủy hẹn giờ. –

+1

@BradleyUffner: VB cung cấp cho bạn sự linh hoạt để khai báo nó với tham số chỉ khi nó cần tham số. Bạn cũng có thể xử lý nhiều sự kiện với các chữ ký khác nhau dưới một phụ theo cách này, ví dụ, cho mục đích ghi nhật ký hoặc gỡ lỗi. Người dùng nên đọc tài liệu trước khi sử dụng sản phẩm của bạn. Sau đó, đó là lựa chọn của họ cho dù luôn luôn chỉ định chữ ký đầy đủ hoặc rút ngắn nó nếu cần thiết. Xem chỉnh sửa của tôi để biết thêm thông tin. – Neolisk

+0

Cảm ơn bạn đã thêm thông tin và tên chính thức thực tế của tính năng này. –

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