2011-01-23 29 views
6

Ví dụ sau đây là đem lại cho tôi lỗi này:
[DCC Error] Unit2.pas(54): E2010 Incompatible types: 'IBar' and 'Unit2.TFoo<Unit2.IBar>'Vấn đề với Generics và các giao diện và thừa kế

Tôi nghĩ rằng vấn đề là ở đâu đó xung quanh Self.Create Bởi vì sau bao nhiêu cố gắng để làm cho nó biên soạn tôi vô tình bước vào FFoo : = TBar (Tự) .Tạo; và nó được biên soạn và làm việc.

Tôi đang sử dụng Delphi XE

IFoo = interface 
end; 

TFoo<T: IInterface> = class(TInterfacedObject, IFoo) 
private class var 
    FFoo: T; 
public class 
    function Instance: T; 
end; 

IBar = interface(IFoo) 
end; 

TBar = class(TFoo<IBar>, IBar) 
end; 

class function TFoo<T>.Instance: T; 
begin 
    if not Assigned(FFoo) then 
    begin 
    FFoo := Self.Create; 
    end; 
    Result := FFoo; 
end; 
+4

Lỗi này cho bạn biết số dòng. Có lẽ bạn có thể chỉ ra chính xác những gì dòng đó là thay vì đoán nơi mà vấn đề có thể được? –

+1

Lỗi nằm trên dòng sau "kết thúc". – RjK

+0

Việc cast 'TBar (Self) .Tạo' là không mong muốn vì bạn không chắc rằng Self là một TBar ** và ** nó sẽ phá vỡ khái niệm generics (không thể sử dụng cho một class khác)! – TridenT

Trả lời

1

TFoo của bạn không thực hiện T là giao diện. Đó là lý do tại sao FFoo và một thể hiện của TFoo không tương thích. Nếu bạn muốn gán một thể hiện của TFoo cho FFoo, bạn cần phải cố định nó.

+0

Bạn có ý nghĩa này trong hàm Instance: Result: = T (FFoo); Nó biên dịch nhưng khi tôi chạy nó, tôi nhận được một AV ở đầu cuối của hàm. (Vi phạm truy cập tại địa chỉ 00000001. Đọc địa chỉ 00000001.) – RjK

3

Vấn đề là trong dòng này với việc kê khai TBar:

FFoo := Self.Create; 

Để hiểu, chúng ta hãy giải thích các loại đằng sau mã [lưu ý như thế này]:

FFoo:[IBar] := Self:[TFoo(IBar)].Create():[TFoo<IBar>] 

Vì vậy, tu tóm tắt, chúng tôi có: [IBar] := [TFoo<IBar>]
Các loại này có tương thích không?
Một [TFoo] chỉ thực hiện IFoo giao diện, không Ibar vì nó được ghi trong mã của bạn

TFoo<T: IInterface> = class(TInterfacedObject, IFoo) 

Đây là lỗi biên dịch!
UPDATE: Giải pháp 1
Để khắc phục vấn đề này: thay đổi tuyên bố TBar

TBar = class(TFoo<IFoo>, IBar) 
end; 

UPDATE: Giải pháp 2
Thay FFoo := Self.Create bởi

FFoo := Self.Create.Instance; 

và vì thế nó công trinh !

+0

Đó không phải là giải pháp vì loại kết quả của hàm Instance sẽ là IFoo chứ không phải IBar. – RjK

+0

@RjK: Tôi đã cập nhật bài đăng của mình với ** Giải pháp 2 **. Tôi nghĩ rằng đây là những gì đã được tìm kiếm! – TridenT

+0

CẬP NHẬT: Giải pháp 2 -> Điều này sẽ gây ra tràn ngăn xếp. – RjK

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