Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there any methods built into the Spring framework that make working with polymorphic containers easier?

I have a dictionary that contains different kinds of values and I want to filter for an item that has a specific sub-type and that satisfies a certain condition:

var
  FData: IDictionary<TGUID, TObject>; // Polymorphic
begin
  TMicroStep(FData.Values.Single(
    function(const O: TObject): Boolean begin
      Result := (O is TMicroStep) and (TMicroStep(O).OrderTag = 1);
  end))
end;

It works, but it looks ugly, because of the type check and double cast.

Maybe something like this might be possible?

var
  FData: IDictionary<TGUID, TObject>; // Polymorphic
begin
  FData.Values.SingleSubType<TMicroStep>(
    function(const MS: TMicroStep): Boolean begin
      Result := MS.OrderTag = 1;
  end))
end;

Does Spring have anything that can help me here?

like image 384
Jens Mühlenhoff Avatar asked Oct 19 '25 04:10

Jens Mühlenhoff


1 Answers

Unfortunately Delphi does not support parameterized methods in interfaces. That is why IEnumerable<T> does not have methods like OfType<TResult>.

You could use a static method like we provide in TCollections (or with 1.2 in the new static type TEnumerable that provides those methods) but I don't know if you like that any better than what you already have:

TEnumerable.OfType<TObject, TMicroStep>(FData.Values).Single(
  function(const MS: TMicroStep): Boolean
  begin
    Result := MS.OrderTag = 1;
  end);

The method would look like this (untested but should work):

class function TEnumerable.OfType<T, TResult>(
  const source: IEnumerable<T>): IEnumerable<TResult>;
begin
  Result := TOfTypeIterator<T, TResult>.Create(source);
end;

TOfTypeIterator<T,TResult> is from Spring.Collections.Extensions.

The type check in its MoveNext method certainly can be improved when dealing with classes to avoid TValue.

like image 155
Stefan Glienke Avatar answered Oct 21 '25 09:10

Stefan Glienke