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,或TFilterElementTSlicerElement 的任何其他共同祖先:

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,并将 TFilterElementTSlicerElement 作为后代类?

【讨论】:

@@Andreas - 这行得通,但我必须根据 TFilterElement 或 TSlicerElement 投射我的回报。我可以这样做...你能解释一下为什么我的 Variant 方法不起作用吗? @user1009073:Variants 无法容纳对象。 (见第二段。) @user1009073:如果你发现你写的代码块包含TFilterElement(MyThing)很多次,那么声明一个TFilterElement类型的变量是个好主意——比如MyFilter -- 并将对象分配给这个变量:MyFilter := TFilterElement(MyThing)。然后您可以在以后每次出现时使用MyFilter。 (但只有在您确认 MyThing 确实是 TFilterElement 后才能执行此操作。)您也可以使用 absolute 关键字。 使用接口怎么样?

以上是关于Delphi - 如何从函数返回不同的类型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Swift 从一个函数返回不同类型的结构?

请问delphi中pchar()是个啥函数,返回啥值?

如何从 Delphi 调用 Oracle 函数?

Delphi中返回类型为string的函数的一个陷阱(不是很懂)

C ++如何从具有不同返回类型的接口多重继承?

为啥原始类型和用户定义类型在从函数返回为“const”时表现不同?