Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 为什么此赋值会导致编译器错误?_Delphi_Interface - Fatal编程技术网

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.