gpt4 book ai didi

delphi - 在过程中传递不同的记录类型作为参数?

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

是否有技巧可以在过程中将不同类型的记录作为参数传递?例如,看看这个伪代码:

type
TPerson = record
Species: string;
CountLegs: Integer;
end;

TSpider = record
Species: string;
CountLegs: Integer;
Color: TColor;
end;

var
APerson: TPerson;
ASpider: TSpider;

// Is there a trick to pass different record types as parameter in a procedure?:
procedure DoSomethingWithARecord(const ARecord: TAbstractRecord?);
begin
if ARecord is TPerson then
DoSomethingWithThisPerson(ARecord as TPerson)
else if ARecord is TSpider then
DoSomethingWithThisSpider(ARecord as TSpider);
end;

procedure DefineRecords;
begin
APerson.Species := 'Human';
APerson.CountLegs := 2;
ASpider.Species := 'Insect';
ASpider.CountLegs := 8;
ASpider.Color := clBtnFace;
DoSomethingWithARecord(APerson);
DoSomethingWithARecord(ASpider);
end;

最佳答案

记录实例不像类那样包含类型信息。因此,您需要传递一个额外的参数来指示您正在使用哪种类型。例如:

type
TRecordType = (rtPerson, rtSpider);

procedure DoSomething(RecordType: TRecordType; const ARecord);
begin
case RecordType of
rtPerson:
DoSomethingWithThisPerson(TPerson(ARecord));
rtSpider:
DoSomethingWithThisSpider(TSpider(ARecord));
end;
end;

您可能会考虑将类型代码放在每个记录的第一个字段中:

type
TPerson = record
RecordType: TRecordType;
Species: string;
CountLegs: Integer;
end;

TSpider = record
RecordType: TRecordType;
Species: string;
CountLegs: Integer;
Color: TColor;
end;

function GetRecordType(ARecord): TRecordType;
begin
Result := TRecordType(ARecord);
end;

....

procedure DoSomething(const ARecord);
begin
case GetRecordType(ARecord) of
rtPerson:
DoSomethingWithThisPerson(TPerson(ARecord));
rtSpider:
DoSomethingWithThisSpider(TSpider(ARecord));
end;
end;

您可以使用泛型:

type
TMyRecordDispatcher = record
class procedure DoSomething<T: record>(const Value: T); static;
end;

class procedure TMyRecordDispatcher.DoSomething<T>(const Value: T);
begin
if TypeInfo(T) = TypeInfo(TPerson) then
DoSomethingWithThisPerson(PPerson(@Value)^)
else if TypeInfo(T) = TypeInfo(TSpider) then
DoSomethingWithThisSpider(PSpider(@Value)^);
end;

并像这样调用函数:

TMyRecordDispatcher.DoSomething(APerson);
TMyRecordDispatcher.DoSomething(ASpider);

这使用泛型类型推断,因此允许您不必显式声明类型。尽管作为泛型的一个例子,它让我感到畏缩。请不要这样做。

在我看来,所有这些都是困惑且脆弱的。上面的大部分内容重新实现了运行时方法分派(dispatch)、多态性。类更适合这个。我不认可上面的任何代码。

另一方面,也许这都是不必要的。有什么问题:

DoSomethingWithThisPerson(Person);
DoSomethingWithThisSpider(Spider);

既然您在编译时就知道类型,为什么要选择更复杂的东西呢?

您可以使用函数重载来省略函数名称中的类型。

procedure DoSomething(const APerson: TPerson); overload;
begin
....
end;

procedure DoSomething(const ASpider: TSpider); overload;
begin
....
end;

....

DoSomething(Person);
DoSomething(Spider);

关于delphi - 在过程中传递不同的记录类型作为参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28750832/

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