delphirttitvalue

Setting TValue record in Delphi from known type with RTTI


I have data that is being read in to a RESTful server in the form of name=value pairs.

The server code has a mapping of allowed "name" with a corresponding Delphi type and I wish to convert the "value" part (which is received in string format) to a corresponding TValue variable which is used further along in the processing chain.

Short of setting up a big if/else statement that tests for the mapped type of the "name" is there any way that RTTI can help out. I can get the PTypeInfo of the mapped type using the FindType method of TRTTIContext, and I can see some TValue methods that take a PTypeInfo parameter.

At this stage I've looked at TValue.Cast and TValue.Make but they fail when converting '10' to an Integer.

Do I just go back to the if/else approach and handle the types I need to deal with ?


Solution

  • TValue represents the same implicit casts that the compiler supports. For example, Int16<->Integer, but not String<->Integer. Those kind conversions, you have to do yourself

    I would probably do something like this:

    type
      ConvFunc = function(const Value: String): TValue;
    
    function ConvToInt(const Value: String): TValue;
    begin
      Result := StrToInt(Value);
    end;
    
    // other conversion functions as needed...
    
    var
      Dict: TDictionary<String, ConvFunc>;
      Func: ConvFunc;
      Value: TValue;
    begin
      Dict := TDictionary<String, ConvFunc>.Create;
    
      Dict.Add('name', @ConvToInt);
      // add other entries as needed...
      ...
    
      if not Dict.TryGetValue('NameToFind', Func) then
      begin
        // name is not supported...
      end else
      begin
        try
          Value := Func('InputToConvert');
          // use Value as needed...
        except
          // input is not supported...
        end;
      end;
      ...
    
      Dict.Free;
    end;