如何确定 TJSONNumber 是 double 还是 Integer?

Wol*_*res 4 delphi json numbers

我正在编写一个通用调用来通过 JSON 存储和检索数据。因此,当从 JSON 加载数据时,我可以验证它是否是 aTJSONNumber但缺乏正确的方法来确定它是否是integerdouble。目前我是这样做的,但我想还有更好的方法吗?

FDataStore: TDictionary<string, Variant>;


for index := 0 to Value.Count - 1 do begin
   Pair := Value.Pairs[Index];
   if Pair.JsonValue is TJSONNumber then
        try
          FDataStore.AddOrSetValue(Pair.JsonString.Value, (Pair.JsonValue as TJSONNumber).AsInt);
        except
          FDataStore.AddOrSetValue(Pair.JsonString.Value, (Pair.JsonValue as TJSONNumber).AsDouble);
        end;
end;
Run Code Online (Sandbox Code Playgroud)

Rem*_*eau 7

不幸的是,它TJSONNumber并没有告诉你实际的类型,所以你必须自己解析原始文本才能弄清楚。

例如,通过使用TryStrToInt64()(而不是try..except),例如:

var
  IntValue: Int64;
  V: Variant;

if TryStrToInt64(TJSONNumber(Pair.JsonValue).Value, IntValue) then
begin
  if IntValue >= Min(Integer) and IntValue <= Max(Integer) then
    V := Integer(IntValue)
  else
    V := IntValue;
end else
  V := TJSONNumber(Pair.JsonValue).AsDouble);

FDataStore.AddOrSetValue(Pair.JsonString.Value, Value);
Run Code Online (Sandbox Code Playgroud)

或者,您可以扫描 JSON 字符串中的'.'和字符(JSON 数字中除了和'E'之外唯一允许的非数字字符),例如:'+''-'

var
  V: Variant;

if LastDelimiter('.Ee', TJSONNumber(Pair.JsonValue).Value) = 0 then
begin
  var IntValue := TJSONNumber(Pair.JsonValue).AsInt64;
  if IntValue >= Min(Integer) and IntValue <= Max(Integer) then
    V := Integer(IntValue)
  else
    V := IntValue
end
else
  V := TJSONNumber(Pair.JsonValue).AsDouble;

FDataStore.AddOrSetValue(Pair.JsonString.Value, V);
Run Code Online (Sandbox Code Playgroud)

请注意,TJSONNumber也可以转换为UIntUInt64,因此您可能还需要考虑处理这些类型。