I want a procedure that does something like this:
procedure RecordStringToLower(var MyRecord);
begin
// 1. Loop through all fields
// 2. Find string fields
// 3. Convert all string fields to lowercase
end;
I know there are probably various ways to accomplish this, but it'll probably need to happen via generics and RTTI?. Any suggestions?
I'm not picky at all in terms of how the procedure or function works.
I tried a couple of different things, and this is the closest that I came, but it doesn't work:
class procedure TRecordHelper.RecordStringToLower<T>(var ARecord: T);
begin
var Context := TRttiContext.Create;
try
var RttiType := Context.GetType(TypeInfo(T));
for var Field in RttiType.GetFields do
begin
if (Field.FieldType.TypeKind = TTypeKind.tkString) then
Field.SetValue(@ARecord, Field.GetValue(@ARecord).AsString.ToLower);
end;
finally
Context.Free;
end;
end;
I don't understand RTTI enough.
You are on the right track, you are just looking for the wrong type kind. Each string type has its own TTypeKind
value, ie:
tkString
for ShortString
tkUString
for UnicodeString
tkLString
for AnsiString
tkWString
for WideString
So, make sure you handle all of the kinds of strings your code actually uses, eg:
class procedure TRecordHelper.RecordStringToLower<T>(var ARecord: T);
begin
var Context := TRttiContext.Create;
try
var RttiType := Context.GetType(TypeInfo(T));
for var Field in RttiType.GetFields do
begin
case Field.FieldType.TypeKind of
TTypeKind.tkString,
TTypeKind.tkUString,
TTypeKind.tkLString,
TTypeKind.tkWString:
Field.SetValue(@ARecord, Field.GetValue(@ARecord).AsString.ToLower);
end;
end;
finally
Context.Free;
end;
end;