David Moorhouse
David Moorhouse

Reputation: 1665

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 ?

Upvotes: 1

Views: 1054

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 598299

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;

Upvotes: 2

Related Questions