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?
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.