Delphi - 如何从函数返回不同的类型
Posted
技术标签:
【中文标题】Delphi - 如何从函数返回不同的类型【英文标题】:Delphi - How to return different types from a function 【发布时间】:2020-06-24 15:08:22 【问题描述】:Delphi Rio - 我正在编写一个类,其中一个函数是 AddFilter。当 AddFilter 类被执行时,根据各种因素,它要么创建一个过滤器,要么创建一个切片器。 (想想 Excel 过滤器和切片器)。我希望该函数返回新创建的对象,即 tFilterElement 或 tSlicerElement,它们是独立的、不相关的类。我的挑战是如何拥有一个可以返回新创建的对象的函数;哪个可以是 2 个不同的类之一?我想在这里使用变体,但我无法让它工作。伪代码是
function TPivotTable.addFilter(params...):Variant;
var
E1 : tFilterElement;
E2 : tSlicerElement;
begin
... if this can be a Filter
E1 := TFilterElement.Create(params);
result := E1;
... else
E2 := TSlicerElement.Create;
result := E2;
end;
我试过了
result := E1 as Variant;
还有
result := Variant(E1);
但两者都不起作用。有没有办法做到这一点?我与变体无关,只是想不出任何其他可行的方法。
【问题讨论】:
【参考方案1】:您始终可以将结果类型声明为TObject
,或TFilterElement
和TSlicerElement
的任何其他共同祖先:
function TPivotTable.AddFilter(...): TObject;
begin
if SomeCondition then
Result := TFilterElement.Create
else
Result := TSlicerElement.Create;
end;
当你使用这个函数时,你必须调查结果并查看它是什么类:
MyThing := MyPivotTable.AddFilter(...);
if MyThing is TFilterElement then
TFilterElement(MyThing).DoSomeFilterStuff
else if MyThing is TSlicerElement then
TSlicerElement(MyThing).DoSomeSlicerStuff
else
raise Exception.Create('Neither a filter nor a slicer was returned.');
说了这么多,这似乎是一个相当糟糕的设计。 (所有is
检查和强制转换都是这种情况的标志。)
我不知道您的应用程序,但也许您可以创建一个类 TElement
,并将 TFilterElement
和 TSlicerElement
作为后代类?
【讨论】:
@@Andreas - 这行得通,但我必须根据 TFilterElement 或 TSlicerElement 投射我的回报。我可以这样做...你能解释一下为什么我的 Variant 方法不起作用吗? @user1009073:Variants 无法容纳对象。 (见第二段。) @user1009073:如果你发现你写的代码块包含TFilterElement(MyThing)
很多次,那么声明一个TFilterElement
类型的变量是个好主意——比如MyFilter
-- 并将对象分配给这个变量:MyFilter := TFilterElement(MyThing)
。然后您可以在以后每次出现时使用MyFilter
。 (但只有在您确认 MyThing
确实是 TFilterElement
后才能执行此操作。)您也可以使用 absolute
关键字。
使用接口怎么样?以上是关于Delphi - 如何从函数返回不同的类型的主要内容,如果未能解决你的问题,请参考以下文章