2013-10-30 17 views
7

Tôi hiện đang mắc kẹt với một lỗi biên dịch, không ai trong công ty của chúng tôi có thể giúp đỡ và tôi thật không may khi không tìm đúng mẫu tìm kiếm cho SO hoặc google.Delphi - Giao diện thừa kế với generics

Vì mã tôi đang sử dụng 2 Giao diện, được kế thừa và 2 Lớp, được kế thừa. Các mã sau tái tạo các lỗi:

program Project22; 

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

Các lỗi biên dịch cho 'TKeyObjectStorage' là:

[DCC Error] Project22.dpr(11): E2514 Type parameter 'T' must support interface 'IStorageObject'

gì tôi nghĩ là, rằng trình biên dịch không thừa nhận rằng Thông số T của TKeyObjectStorage các' Class 'đúng. Cần phải chính xác, vì Loại 'IKeyStorageObject' mong muốn có loại IStorageObject cha.

Tại sao tính năng này không hoạt động? Tôi đang làm gì sai? Điều này là không thể trong Delphi?

+0

Bạn chỉ hoàn toàn thay đổi câu hỏi !!? Bạn vừa thay thế dấu phẩy đó bằng dấu chấm phẩy? !! Và mã bạn đăng vẫn không đủ để hiển thị lỗi.Vui lòng làm những gì tôi đề xuất và đăng ** chương trình hoàn chỉnh **. Tôi đã cho bạn thấy làm thế nào trong câu trả lời của tôi. –

+0

Xin lỗi vì David này, Vâng tôi đã làm, nhưng ',' đã không ném một hoặc lỗi này và chỉ là một sự giám sát nhỏ. Sry lần nữa. – Hugie

+0

@Hugie, Không thay đổi câu hỏi để đi chệch khỏi vấn đề ban đầu của nó. Bất kỳ lỗi nào trong nhu cầu ban đầu cần lưu lại trong câu hỏi; tuy nhiên tạo một ứng dụng giao diện điều khiển với mã tối thiểu để chứng minh sự cố. và dán ** ứng dụng giao diện điều khiển ** đó vào câu hỏi. – Johan

Trả lời

9

Cập nhật

Các câu hỏi ban đầu đã có một vấn đề mà tôi xác định (xem dưới đây). Tuy nhiên, sửa chữa tôi mô tả có tốt cho XE3 và sau đó, nhưng chương trình dưới đây không biên dịch trong XE2. Vì vậy, tôi kết luận rằng đây là một lỗi trình biên dịch Generics Generics.

Dù sao, đây là một cách giải quyết cho Delphi XE2:

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>, IStorageObject> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IStorageObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

Original câu trả lời

Nó sẽ tốt hơn nếu bạn đã cung cấp một chương trình hoàn chỉnh trưng bày các lỗi biên dịch . Bạn cần cố gắng khởi tạo một đối tượng để xem lỗi đó.

Nhưng, tôi nghĩ rằng tôi đã sao chép sự cố của bạn. Vì vậy, tôi tin rằng vấn đề là mã này:

TKeyObjectStorage<TKey, T: IKeyStorageObject<TKey>> = ... 

áp dụng các hạn chế chung cho cả hai TKeyT. Bây giờ, rõ ràng bạn chỉ muốn hạn chế để áp dụng cho T vì vậy bạn sẽ cần phải viết:

TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = ... 

Dưới đây là một chương trình ngắn mà biên dịch sau sự thay đổi trong Delphi XE3:

{$APPTYPE CONSOLE} 
type 
    IStorageObject = interface(IInterface) 
    end; 
    TObjectStorage<T: IStorageObject> = class(TObject) 
    end; 
    IKeyStorageObject<TKey> = interface(IStorageObject) 
    end; 
    TKeyObjectStorage<TKey; T: IKeyStorageObject<TKey>> = class(TObjectStorage<T>) 
    end; 
    TImplementingClass<TKey> = class(TInterfacedObject, IKeyStorageObject<TKey>) 
    end; 
begin 
    TKeyObjectStorage<Integer, TImplementingClass<Integer>>.Create; 
end. 

này khá là một sắc thái, việc thay đổi dấu phẩy thành dấu chấm phẩy. Lập trình bằng dấu chấm câu quan trọng không bao giờ thú vị nhiều. Điều đó nói rằng, bạn đã quen thuộc với sự khác biệt giữa dấu phẩy và dấu chấm phẩy trong danh sách tham số chính thức và vì vậy nó không nên đến quá nhiều bất ngờ để thấy sự phân biệt giống nhau được vẽ ở đây.

Các documentation không che tâm trí này, bạn:

Multiple Type Parameters

When you specify constraints, you separate multiple type parameters by semicolons, as you do with a parameter list declaration:

type 
    TFoo<T: ISerializable; V: IComparable> 

Like parameter declarations, multiple type parameters can be grouped together in a comma list to bind to the same constraints:

type 
    TFoo<S, U: ISerializable> ... 

In the example above, S and U are both bound to the ISerializable constraint.

+1

Thx David, tôi đã chỉnh sửa mã của mình thành một đơn vị hoàn chỉnh (không có instantiation) và nó tái tạo lỗi trong một dự án sạch. Và có, bạn đã đúng, tôi đã có một sai lầm nhỏ hợp lý do, ->; nhưng đó không phải là lỗi mà tôi đang xử lý. Thx cho nỗ lực của bạn. – Hugie

+0

Bản cập nhật của bạn không tạo ra lỗi. Thử nó. Bắt đầu với một dự án mới, và thêm đơn vị đó, và sau đó biên dịch. Đoán cái gì, nó biên dịch. Như tôi đã nói trong câu trả lời của tôi, bạn cần phải khởi tạo một đối tượng. Tôi hơi thất vọng vì điều này. Bạn cần phải học cách tạo ra một SSCCE để bạn không lãng phí thời gian của chúng ta. Tôi đi ăn trưa bây giờ. Tôi hy vọng câu hỏi này sẽ được sửa vào thời điểm tôi quay trở lại. –

+1

Tôi đã sao chép mã của bạn vào XE2, nó vẫn đưa ra một lỗi: '[Lỗi DCC] Project22.dpr (11): E2514 Tham số kiểu 'T' phải hỗ trợ giao diện 'IStorageObject'' trên dòng này:' TKeyObjectStorage < TKey; T: IKeyStorageObject > = class (TObjectStorage ) ' – Johan

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