Assuming you did not specify a TList.Create constructor in the constructor, you will get TComparer<TSomeRecord>.Default as your comparator. And this is a CompareMem that performs simple binary comparisons using CompareMem .
This is great for writing full value types, without padding. But otherwise, you will need to provide your own comparison function when creating the list instance.
If you want to see the details, the default mapping for records is implemented in Generics.Defaults . For large records, the comparison is this function:
function Equals_Binary(Inst: PSimpleInstance; const Left, Right): Boolean; begin Result := CompareMem(@Left, @Right, Inst^.Size); end;
For smaller entries, there is optimization, and your companion will be a 4-byte comparator. It looks like this:
function Equals_I4(Inst: Pointer; const Left, Right: Integer): Boolean; begin Result := Left = Right; end;
This is a bit strange, but it interprets 4 bytes of your record as an integer of 4 bytes and performs an integer equality comparison. In other words, the same as CompareMem , but more efficient.
The component you want to use might look like this:
TComparer<TSomeRecord>.Construct( function const Left, Right: TSomeRecord): Integer begin Result := CompareStr(Left.Value, Right.Value); end; )
Use CompareText if you want case insensitive and so on. I used an ordered comparison function because this is what TList<T> wants.
The fact that comparing records by default is a comparison of equality suggests that attempts to sort record lists without specifying your own comparator will have unexpected results.
Given that the default mapper uses comparison comparisons, you say that it would be inappropriate to use such a comparator:
TComparer<TSomeRecord>.Construct( function const Left, Right: TSomeRecord): Integer begin Result := ord(not (Left = Right)); end; )
This will be fine for unordered operations such as IndexOf or Contains , but is not explicitly used for sorting, binary search, etc.