Regression: RTTI information is missing in IList<T>
The “develop” branch of Spring4D misses RTTI information in IList<T> (and possibly in other interfaces as well). The “master” branch includes RTTI information in IList<T>.
As a result “develop” Spring4D interfaces cannot be serialized/deserialized with RTTI any more.
Please add serializable versions of Spring4D interfaces that include RTTI. E.g. ISerializableList<T> and/or similar.
Test code:
procedure ListIListMethods;
var
MyContext: TRttiContext;
MyRttiType: TRttiType;
MyMethod: TRttiMethod;
begin
MyContext := TRttiContext.Create;
MyRttiType := MyContext.GetType(TypeInfo(IList<Integer>));
for MyMethod in MyRttiType.GetMethods do
Writeln(MyMethod.Name);
end;
Comments (4)
-
repo owner -
repo owner - changed status to wontfix
-
reporter You fail to see that I do not have access to IEnumerable and ICollection unless I create a dependency on Spring4D (add Spring4D units to uses). RTTI allows me to decouple the serialization engine from Spring4D.
If you create dedicated interfaces that include RTTI information you won’t have any overhead in base interfaces:
IList<T> - no RTTI, no overhead
ISerializableList<T> - with RTTI, with overheadOnly people who want or need the RTTI will use the ISerializableList<T> interfaces. So no overhead for the others.
-
reporter Here is a proof-of-concept code for ISerializableList<T>:
{$M+} ISerializableEnumerator<T> = interface ['{FF1CF9C5-AA17-4903-B5E2-BB954F65D46B}'] function GetCurrent: T; function MoveNext: Boolean; end; TSerializableEnumerator<T> = class(TInterfacedObject, ISerializableEnumerator<T>) var fEnumerator: Spring.Collections.IEnumerator<T>; public function GetCurrent: T; function MoveNext: Boolean; constructor Create(const aEnumerator: Spring.Collections.IEnumerator<T>); end; {$M+} ISerializableList<T> = interface(Spring.Collections.IList<T>) ['{2D89E86C-69F9-444A-ADAE-81A1B5BC1C9F}'] function Add(const item: T): Integer; procedure Clear; function GetEnumerator: ISerializableEnumerator<T>; end; TSerializableFoldedList<T> = class(TFoldedList<T>, ISerializableList<T>) public function GetEnumerator: ISerializableEnumerator<T>; end; [xml('myserobject')] TSerObject = record [xmlcollection(''), xml('mylist')] List: ISerializableList<IItem>; end; TCollectionsHelper = class helper for TCollections public class function CreateSerializableList<T>: ISerializableList<T>; overload; static; end; { TCollectionsHelper } class function TCollectionsHelper.CreateSerializableList<T>: ISerializableList<T>; begin Result := TSerializableFoldedList<T>.Create(TypeInfo(T), nil); end; { TSerializableFoldedList<T> } function TSerializableFoldedList<T>.GetEnumerator: ISerializableEnumerator<T>; begin Result := TSerializableEnumerator<T>.Create(inherited GetEnumerator); end; { TSerializableEnumerator<T> } constructor TSerializableEnumerator<T>.Create( const aEnumerator: Spring.Collections.IEnumerator<T>); begin inherited Create; fEnumerator := aEnumerator; end; function TSerializableEnumerator<T>.GetCurrent: T; begin Result := fEnumerator.Current; end; function TSerializableEnumerator<T>.MoveNext: Boolean; begin Result := fEnumerator.MoveNext; end;
- Log in to comment
This is as designed as RTTI adds quite some overhead - it does not require RTTI to serialize and deserialize collections.
You can use the non generic interfaces IEnumerable and ICollection to serialize and deserialize almost every collection.