Trong Delphi, IUnknown
được khai báo là:Delphi: Làm thế nào để triển khai QueryInterface của IUnknown?
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
Lưu ý: Các tham số đầu ra là untyped
Trong TInterfacedObject
hậu duệ của tôi tôi cần phải xử lý QueryInterface
, vì vậy tôi có thể trả về một đối tượng có hỗ trợ các yêu cầu giao diện:
function TFoo.QueryInterface(const IID: TGUID; out Obj): HResult;
begin
if IsEqualGUID(IID, IFooBar) then
begin
Obj := (TFooBar.Create(Self) as IFooBar);
Result := S_OK;
end
else
Result := inherited QueryInterface(IID, {out}Obj);
end;
Sự cố xảy ra trên dòng:
Obj := (TFooBar.Create(Self) as IFooBar);
Delphi phàn nàn:
điều hành không áp dụng đối với loại toán hạng này
Rõ ràng tôi không biết làm thế nào hoặc những gì để gán cho một tham số untyped out
. tôi có thể thử một cách ngẫu nhiên mọi thứ, với hy vọng rằng trình biên dịch sẽ ngừng phàn nàn:
Obj := TFooBar.Create(Self);
Obj := Pointer(TFooBar.Create(Self));
Obj := Pointer(TFooBar.Create(Self) as IFooBar);
Bỏ qua tất cả các mã tôi đã viết (nếu cần): làm thế nào để tôi thực hiện QueryInterface
trong một hậu duệ đối tượng từ TInterfacedObject
?
Vấn đề thực sự tôi đã cố gắng để giải quyết có thể được luộc xuống tôi muốn:
tôi muốn ghi đè lên các phương pháp trong một giao diện
Trong cùng một cách :
TList = class(TObject)
...
function GetItem(Index: Integer): Pointer;
procedure SetItem(Index: Integer; Value: Pointer);
property Items[Index: Integer]: Pointer read GetItem write SetItem;
end;
có thể được ghi đè trong lớp hậu duệ:
TStudentList = class(TList)
...
function GetItem(Index: Integer): TStudent;
procedure SetItem(Index: Integer; Value: TStudent);
property Items[Index: Integer]: TStudent read GetItem write SetItem;
end;
tôi muốn nên giống với giao diện:
IFoo = interface(IUnknown)
...
function GetItem(Index: Variant): Variant;
procedure SetItem(Index: Variant; Value: Variant);
property Items[Index: Variant]: Variant read GetItem write SetItem;
end;
IFooGuidString = interface(IFoo)
...
function GetItem(Index: TGUID): string ;
procedure SetItem(Index: TGUID; Value: string);
property Items[Index: TGUID]: string read GetItem write SetItem;
end;
Vấn đề là làm thế nào tôi có để bắt đầu tải lên đối tượng thực hiện của tôi với:
TFoo = class(TInterfacedObject, IFoo, IFooGuidString)
public
function IFoo.GetItem = FooGetItem;
procedure IFoo.SetItem = FooSetItem;
function FooGetItem(Index: Variant): Variant;
procedure FooSetItem(Index: Variant; Value: Variant);
function IFooGuidString.GetItem = FooGuidStringGetItem;
procedure IFooGuidString.SetItem = FooGuidStringSetItem;
function FooGuidStringGetItem(Index: TGUID): string ;
procedure FooGuidStringSetItem(Index: TGUID; Value: string);
end;
Và có không chỉ là hai phương pháp trong IFoo
, có 6. Và sau đó nếu tôi muốn thêm một giao diện được hỗ trợ khác:
IFooInt64String = interface(IFoo)
...
function GetItem(Index: Int64): string ;
procedure SetItem(Index: Int64; Value: string);
property Items[Index: Int64]: string read GetItem write SetItem;
end;
TFoo = class(TInterfacedObject, IFoo, IFooGuidString)
public
function IFoo.GetItem = FooGetItem;
procedure IFoo.SetItem = FooSetItem;
function FooGetItem(Index: Variant): Variant;
procedure FooSetItem(Index: Variant; Value: Variant);
function IFooGuidString.GetItem = FooGuidStringGetItem;
procedure IFooGuidString.SetItem = FooGuidStringSetItem;
function FooGuidStringGetItem(Index: TGUID): string ;
procedure FooGuidStringSetItem(Index: TGUID; Value: string);
function IFooInt64String.GetItem = FooInt64StringGetItem;
procedure IFooInt64String.SetItem = FooInt64StringSetItem;
function FooInt64StringGetItem(Index: Int64): string ;
procedure FooInt64StringSetItem(Index: Int64; Value: string);
end;
Và mọi thứ trở nên thực sự khó sử dụng rất nhanh.
Tôi khuyến khích bạn đăng câu hỏi về "vấn đề thực sự" của bạn. Nghe có vẻ thú vị, và tôi có một ý tưởng mơ hồ về cách làm điều đó (một cái gì đó về * aggregates * và * containers *). Bạn có thể thấy rằng bạn đang viết nhiều mã hơn bạn cần. –
@Rob Kennedy Nếu bạn có thể nghĩ về một tiêu đề hữu ích cho nó, điều đó sẽ tạo ra sự quan tâm, tôi chắc chắn sẽ làm điều đó. tôi thấy rằng nếu không có một móc * tốt, câu hỏi sẽ không được trả lời. Câu hỏi này là tốt, bởi vì câu hỏi, như được diễn đạt, nghe có vẻ dễ dàng - vì vậy tôi đã hút những người nghĩ rằng họ có thể cho tôi một việc học dễ dàng. Mặt khác, bạn và Uwe dường như tuần tra cho các câu hỏi Delphi :) –