【问题标题】:Delphi - How to return different types from a functionDelphi - 如何从函数返回不同的类型
【发布时间】: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);

但两者都不起作用。有没有办法做到这一点?我与变体无关,只是想不出任何其他可行的方法。

【问题讨论】:

    标签: function delphi variant


    【解决方案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 关键字。
    • 使用接口怎么样?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多