gpt4 book ai didi

delphi - Delphi 7 和 Delphi XE 及更高版本之间接口(interface)的不同行为

转载 作者:行者123 更新时间:2023-12-03 18:08:22 25 4
gpt4 key购买 nike

我在不同版本的 Delphi 中使用界面时遇到一个奇怪的问题。以下最小化代码在 Delphi XE 和更高版本中按预期编译和运行,但在 Delphi 7 中没有。具体来说,在 Delphi 7 中编译时,function TForm1.Load: IMoleculeSubject; 似乎没有返回正确的结果,即对新创建实例的正确引用。你能帮忙评论一下原因和可能的解决方法吗?非常感谢!

uInterface.pas

    unit uInterface;

interface

type

IMoleculeSubject = interface
['{BEB4425A-186C-45DF-9DCE-C7175DB0CA90}']
end;

TMoleculeSubject = class(TInterfacedObject, IMoleculeSubject)
end;

implementation

end.

uBusiness.pas

    unit uBusiness;

interface

uses
uInterface;

type

TMoleculeDecorator = class(TMoleculeSubject)
private
FID: Integer;
public
property ID: Integer read FID;
constructor Create;
end;

implementation

{ TMoleculeDecorator }

constructor TMoleculeDecorator.Create;
begin
inherited Create;

FID := Random(100);
end;

end.

Unit1.pas

    unit Unit1;

interface

uses
uInterface, uBusiness,

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs;

type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
function Load: IMoleculeSubject;
public
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
MolSubject: IMoleculeSubject;
begin
MolSubject := Load;

// The down-cast is to show the returned result is wrong in Delphi 7!
Caption := IntToStr(TMoleculeDecorator(MolSubject).ID);
end;

function TForm1.Load: IMoleculeSubject;
var
MolSubject: IMoleculeSubject;
begin
MolSubject := TMoleculeDecorator.Create;
Result := MolSubject;
end;

end.


最佳答案

Load 函数在所有版本的 Delphi 中都运行良好。问题在于您的转换,即所谓的不安全类型转换。从接口(interface)引用到对象的不安全类型转换在旧版本的 Delphi 中具有错误定义的行为。然而,行为在现代 Delphi 中是明确定义的。 documentation说得更多。

因此,基本问题是您对该行为的期望与该语言的 Delphi 7 版本不兼容。

如果你得到返回ID的接口(interface)你会发现你创建的接口(interface)是符合预期的。

program InterfaceDemo;

{$APPTYPE CONSOLE}

uses
Classes;

type
IMyIntf = interface
function GetID: Integer;
end;

TImplementingObject = class(TInterfacedObject, IMyIntf)
private
FID: Integer;
function GetID: Integer;
public
constructor Create;
end;

{ TImplementingObject }

constructor TImplementingObject.Create;
begin
FID := Random(100);
Writeln(FID);
end;

function TImplementingObject.GetID: Integer;
begin
Result := FID;
end;

var
MyIntf: IMyIntf;

begin
Randomize;
MyIntf := TImplementingObject.Create;
Writeln(MyIntf.GetID);
Readln;
end.

从接口(interface)请求实现对象是相当不寻常的。这样做表明您的设计存在问题。如果您确实需要这样做,有以下几种选择:

后一种选择适用于所有版本的 Delphi,并且无需诉诸诡计。

关于delphi - Delphi 7 和 Delphi XE 及更高版本之间接口(interface)的不同行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14558704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com