Reputation: 3238
Delphi Rio - I am writing a class, where one of the functions is AddFilter. When the AddFilter class is executed, depending on various factors it will either create a filter, or create a slicer. (Think of Excel Filters and Slicers). I want the function to return the newly created object, which is either tFilterElement, or tSlicerElement, which are separate, non-related classes. My challenge is how do I have a function which can return a newly created object; which can be one of 2 different classes? I am trying to use Variants here, but I cannot get this to work. Pseudo Code is
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;
I have tried
result := E1 as Variant;
as well as
result := Variant(E1);
But neither work. Is there a way to do this? I am not tied to Variants, I just couldn't think of any other approach that might work.
Upvotes: 2
Views: 845
Reputation: 108929
You can always declare the result type as TObject
, or any other common ancestor of both TFilterElement
and TSlicerElement
:
function TPivotTable.AddFilter(...): TObject;
begin
if SomeCondition then
Result := TFilterElement.Create
else
Result := TSlicerElement.Create;
end;
When you use this function, you must then investigate the result and see what class it is:
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.');
All this being said, this seems like a rather poor design. (All is
checks and casting is a sign of this.)
I don't know your application, but maybe you could create a class TElement
with TFilterElement
and TSlicerElement
as descendant classes?
Upvotes: 4