I am using the Parallel.ForEach<T>(TEnumerator<T>)where T is a specific interface, derived from, but not equal to IInterface.
Somwhere in the code, the value is cast back to the original type in order to return it to the execute method, but fails with an ETypeCastError using the TValue.AsType because embarcadero obviously forgot to try to try casting the interface to the required one, or otherwise because the otl library internally stored the interface a IInterface rather then the actual specified interface type.
Nevertheless, I came up with a solution that works perfectly, check for my HH markings changed in otlCommon.pas
I don't expect the solution to break any existing code, but I better let you be the judge of that!
function TOmniValue.CastTo<T>: T;
var
ds : integer;
maxValue: uint64;
ti : PTypeInfo;
// HH special support for spciufic interface type
lIntf:IInterface;
lValue:TValue;
// HH end special support
begin
ds := 0;
ti := System.TypeInfo(T);
if assigned(ti) then
if (ti = System.TypeInfo(byte)) or (ti = System.TypeInfo(shortint)) then
ds := 1
else if (ti = System.TypeInfo(word)) or (ti = System.TypeInfo(smallint)) then
ds := 2
else
ds := TOmniValue_DataSize[ti^.Kind];
if ds = 0 then begin // complicated stuff
if ti.Kind = tkRecord then
Result := TOmniRecordWrapper<T>(CastToRecord.Value).Value
else
{$IFDEF OTL_ERTTI}
// HH special support for casting to a specific interface type
if (ti.Kind = tkInterface) and Supports(AsInterface,TGUID(ti.TypeData.IntfGuid),lIntf) then
begin
TValue.Make(@lIntf,ti,lValue);
Result := lValue.AsType<T>;
end
else
// HH end special support
Result := AsTValue.AsType<T>
{$ELSE}
raise Exception.Create('Only casting to simple types is supported in Delphi 2009')
{$ENDIF OTL_ERTTI}
end
else begin // simple types
if ds < 8 then begin
maxValue := uint64($FF) SHL ((ds-1) * 8);
if ovData > maxValue then
raise EOmniValueConv.CreateFmt('Value %d is too big to fit into %s', [ovData, ti^.Name]);
end;
Move(ovData, Result, ds);
end;
end; { TOmniValue.CastTo }
I am using the
Parallel.ForEach<T>(TEnumerator<T>)
whereT
is a specific interface, derived from, but not equal toIInterface
.Somwhere in the code, the value is cast back to the original type in order to return it to the execute method, but fails with an ETypeCastError using the TValue.AsType because embarcadero obviously forgot to try to try casting the interface to the required one, or otherwise because the otl library internally stored the interface a IInterface rather then the actual specified interface type.
Nevertheless, I came up with a solution that works perfectly, check for my HH markings changed in otlCommon.pas I don't expect the solution to break any existing code, but I better let you be the judge of that!