delphi – 将不同的记录类型作为参数传递给过程?
发布时间:2020-12-15 09:37:05 所属栏目:大数据 来源:网络整理
导读:是否有一个技巧可以将不同类型的记录作为参数传递给过程?例如,看看这个伪代码: type TPerson = record Species: string; CountLegs: Integer; end; TSpider = record Species: string; CountLegs: Integer; Color: TColor; end;var APerson: TPerson; ASpi
是否有一个技巧可以将不同类型的记录作为参数传递给过程?例如,看看这个伪代码:
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); 这使用泛型类型推断,因此您不能显式声明类型.虽然作为泛型的一个例子,它让我感到畏缩.请不要这样做. 在我看来,所有这一切都是凌乱和脆弱的.以上大部分重新实现运行时方法调度,多态.类更适合这个.我不赞同上面的任何代码. 另一方面,也许这一切都是不必要的.有什么不对: DoSomethingWithThisPerson(Person); DoSomethingWithThisSpider(Spider); 既然您在编译时知道类型,为什么选择更复杂的东西呢? 您可以使用函数重载来省略函数名称中的类型. procedure DoSomething(const APerson: TPerson); overload; begin .... end; procedure DoSomething(const ASpider: TSpider); overload; begin .... end; .... DoSomething(Person); DoSomething(Spider); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |