2014-12-03 44 views
5

Hãy nói rằng tôi có một lớp với hai phương pháp chung:phương pháp Generic suy luận kiểu

TMyClass = class 
    procedure DoWith<T: class> (obj: T); 
    procedure DoFor<T: class> (proc: TProc<T>); 
end; 

Bây giờ, khi tôi muốn gọi một trong hai phương pháp này với một số loại đặc biệt, Delphi có thể suy ra các loại cho DoWith phương pháp, vì vậy tôi có thể gọi nó với một trong hai

MyClass.DoWith <TButton> (MyButton) 

hoặc

MyClass.DoWith (MyButton) 

Trình biên dịch Delphi sẽ biên dịch cả hai. Nhưng nếu tôi bỏ qua các tham số gõ vào phương pháp DoFor, trình biên dịch Delphi phàn nàn về các tham số kiểu mất tích:

MyClass.DoFor<TButton>(procedure (Button: TButton) begin .... end); // compiles 


MyClass.DoFor(procedure (Button: TButton) begin .... end); // doesn't compile 

Bây giờ câu hỏi của tôi là: Đây có phải là chỉ là một thiếu sót của trình biên dịch, hoặc là có bất kỳ lý do logic (mà tôi đã không tìm ra được nêu ra) mà cấm trình biên dịch từ một cách chính xác suy ra loại cho phương pháp DoFor?

+0

Nó trông giống như một hạn chế của trình biên dịch. Suy luận kiểu chung là rất yếu trong Delphi. –

Trả lời

5

Lý do không thể phỏng đoán T từ đối số TProc<T> là tại thời điểm đó TProc<TButton> là loại được xây dựng mà không có bất kỳ thông tin nào ban đầu là TProc<T>.

Để làm điều đó nó sẽ phải suy ra các loại từ phương pháp chữ ký ẩn danh mà không làm việc (tôi đoán Barry Kelly có thể giải thích rằng tốt hơn và tôi nghĩ anh ấy đã từng viết về những khó khăn của lambdas và suy luận kiểu trong Delphi).

Chỉ loại suy luận trình biên dịch Delphi có khả năng là đối số của loại T. Ngay cả với nhiều đối số không hoạt động thường xuyên và thậm chí ít hơn nếu bạn có nhiều tham số kiểu chung.

Edit: Tôi tìm thấy một bình luận nơi Barry giải thích một chút về những khó khăn của suy luận kiểu và lambdas trong trình biên dịch Delphi: http://www.deltics.co.nz/blog/posts/244/comment-page-1#comment-107

+0

Cảm ơn Stefan: Câu trả lời của bạn đã cho tôi những bit còn thiếu để hiểu rằng có một lý do hợp lý cho hành vi trình biên dịch này. – iamjoosy

+1

@iamjoosy Cá nhân tôi thấy điều này phi lý. Tôi thích nó nếu trình biên dịch sẽ suy ra các loại tốt hơn nhiều. Tôi không thấy lý do tại sao nó không thể làm như vậy. Rất nhiều ngôn ngữ khác quản lý tốt hơn rất nhiều so với Delphi. –

+0

@DavidHeffernan Lúc đầu, tôi không thể thấy bất kỳ logic nào trong trình biên dịch bahaviour, do đó, câu hỏi của tôi ở đây. Nhưng câu trả lời của Stefan mở mắt bằng cách giải thích cách trình biên dịch xử lý biểu thức: Nó xây dựng các kiểu thực tế từ bên trong ra bên ngoài, do đó đầu tiên xây dựng hàm ẩn danh với kiểu TButton và sau đó hoạt động với kiểu này trong thủ tục xung quanh và tại thời điểm này trình biên dịch đã "quên" rằng hàm ẩn danh được xây dựng từ cùng tham số kiểu T mà trang trí hàm xung quanh. – iamjoosy

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