Delphi 为什么此赋值会导致编译器错误?
我正在尝试用接口分离代码。此代码在我的测试工作中:Delphi 为什么此赋值会导致编译器错误?,delphi,interface,Delphi,Interface,我正在尝试用接口分离代码。此代码在我的测试工作中: procedure TTestCustomFrameViewModel.TCreateReturnsIPsFrameViewModel; var LCUT : TInterfacedObject; LCreate : TCreateFrameViewModelFunction; ViewModel : IPsFrameViewModel; begin //Arrange LCUT := nil; LCreate := C
procedure TTestCustomFrameViewModel.TCreateReturnsIPsFrameViewModel;
var
LCUT : TInterfacedObject;
LCreate : TCreateFrameViewModelFunction;
ViewModel : IPsFrameViewModel;
begin
//Arrange
LCUT := nil;
LCreate := CreateFrameTest1ViewModelFunction;
//Act
LCUT := LCreate(nil);
ViewModel := CUT; //Added this assignment just to make sure
//Assert
Assert.Implements<IPsFrameViewModel>(ViewModel);
end;
错误会准确地告诉您问题所在。不能将
TInterfacedObject
分配给IPsFrameViewModel
,也不能分配给它未实现的任何其他接口(除了TInterfacedObject
的IInterface
)。根据定义:
TInterfacedObject = class(TObject, IInterface)
因此,您可以为其分配的唯一接口类型是IInterface
我们看不到第一个代码片段发生了什么,但我们可以假定CUT
不是TInterfacedObject
,而是另一个兼容的对象或接口类型。这似乎也是一个输入错误(你的意思是尝试分配LCUT
?如果是这样的话,那也会失败。)
如果要将常规对象传递给此方法,则需要一个自定义基类,该基类至少实现需要分配给的接口,即:
procedure TfrmTest1.SetViewModel(aViewModel: TMyBaseViewModel);
您可以将TMyBaseViewModel
定义为:
type
IPSFrameViewModel = interface
// ...
end;
IFrameTest1ViewModel = interface
// ...
end;
TMyBaseViewModel = class(TInterfacedObject, IPSFrameViewModel, IFrameTest1ViewModel)
//implement
end;
或者,您可以在运行时使用该方法强制转换接口(如果您喜欢的话)。例如:
procedure TfrmTest1.SetViewModel(aViewModel: TInterfacedObject);
var
LTest : TInterfacedObject;
begin
LTest := aViewModel; //This works
if not Supports(aViewModel, IPSFrameViewModel, FBaseViewModel) then
raise Exception.Create('Object does not support IPSFrameViewModel');
if not Supports(aViewModel, IFrameTest1ViewModel, FFrameTest1ViewModel) then
raise Exception.Create('Object does not support IFrameTest1ViewModel');
FBaseViewModel.Attach(Self);
end;
为此,请注意,您的接口需要使用GUID进行修饰,即:
program program1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
IMyCustomInterface = interface(IInterface)
['{665F462B-C66B-467C-970A-52CAE9C5F69A}']
function Bar : string;
end;
IMyOtherInterface = interface(IInterface)
['{AEAF0D0B-4C6F-480C-A373-98145908B639}']
function Foo : string;
end;
TMyBaseInterfaceObject = class(TInterfacedObject, IMyCustomInterface, IMyOtherInterface)
function Foo : string;
function Bar : string;
end;
function TMyBaseInterfaceObject.Foo : string;
begin
result := 'Hello World Foo.';
end;
function TMyBaseInterfaceObject.Bar : string;
begin
result := 'Hello World Bar.';
end;
var
LMyCustomInterface : IMyCustomInterface;
LMyOtherInterface : IMyOtherInterface;
tio : TInterfacedObject;
begin
tio := TMyBaseInterfaceObject.Create;
if Supports(tio, IMyCustomInterface, LMyCustomInterface) then
WriteLn(LMyCustomInterface.Bar);
if Supports(tio, IMyOtherInterface, LMyOtherInterface) then
WriteLn(LMyOtherInterface.Foo);
ReadLn;
end.
在您的第一个代码段中,有一个未知的标识符。是哪种类型的?谢谢。如果考试没有通过,我就不会问这个问题了???传入的参数将实现这两个接口,我希望在运行时之前不会检查它。回到绘图板上。@GaryShelton Well。。。您可以在运行时进行检查。。。但是您需要使用“支持”例程。你不能直接分配。我在哪里可以找到那个函数上的文档?Delphi帮助未返回任何已关闭的内容。已找到它。谢谢again@GaryShelton,请编辑您的问题以修复打字错误。为了澄清这一点,已经做了太多的努力。
program program1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
IMyCustomInterface = interface(IInterface)
['{665F462B-C66B-467C-970A-52CAE9C5F69A}']
function Bar : string;
end;
IMyOtherInterface = interface(IInterface)
['{AEAF0D0B-4C6F-480C-A373-98145908B639}']
function Foo : string;
end;
TMyBaseInterfaceObject = class(TInterfacedObject, IMyCustomInterface, IMyOtherInterface)
function Foo : string;
function Bar : string;
end;
function TMyBaseInterfaceObject.Foo : string;
begin
result := 'Hello World Foo.';
end;
function TMyBaseInterfaceObject.Bar : string;
begin
result := 'Hello World Bar.';
end;
var
LMyCustomInterface : IMyCustomInterface;
LMyOtherInterface : IMyOtherInterface;
tio : TInterfacedObject;
begin
tio := TMyBaseInterfaceObject.Create;
if Supports(tio, IMyCustomInterface, LMyCustomInterface) then
WriteLn(LMyCustomInterface.Bar);
if Supports(tio, IMyOtherInterface, LMyOtherInterface) then
WriteLn(LMyOtherInterface.Foo);
ReadLn;
end.