About the author
Working on some coding last night, and would like to point out and remind myself how to implement IEnumerable<T> properly.
When implementing IEnumerable<T>, there is always a need to use the method resolution clause in order to avoid conflict of the similar names in IEnumerable and IEnumerable<T>, since both declares the GetEnumerator method with the same type signature.
WORKING EXAMPLE: IEnumerable<T>
type TTestEnumerable<T> = class(TInterfacedObject, IEnumerable<T>) function GenericGetEnumerator: IEnumerator<T>; function GetEnumerator: IEnumerator; function IEnumerable<T>.GetEnumerator = GenericGetEnumerator; end;
Similarly, for IEnumerator<T>:
type TTestEnumerator<T> = class(TInterfacedObject, IEnumerator<T>) function GetCurrent: TObject; function MoveNext: Boolean; procedure Reset; function GenericGetCurrent: T; function IEnumerator<T>.GetCurrent = GenericGetCurrent; end;
The lessons learnt from the above is that whenever interfaces with generic ancestors are involved with similarly named methods, one needs to declare the ancestor interface method, and use method resolution clause to redirect the descendent methods.
While working on the above, I filed QC 116432, on how class completion doesn't work when generics are involved.
How to free more space on your home drive by redirecting the location for SDKs in RAD Studio
Learn the command line used to compile System.pas in Delphi
A method to design records so that they're allocated on a specific byte boundary, such as 16 bytes, 512 bytes, 4096 bytes, etc.
Learn why the map is cool in Go!