通过RTTI将TDateTime值传递给OleVariant属性

问题描述 投票:2回答:1

当我使用RTTI将TDateTime值分配给对象的OleVariant属性时,对象变为Float值。

对象的设计使得此属性可以变为Null或任何数据类型的值。如果它变为浮点数,则应将结果计算为浮点数的差值。如果它变成TDateTime,那么结果应该计算为两个TDateTime值的差值。

我是否已将值直接传递给它,它会正常工作,但中间有RTTI。

我知道TDateTime在内部表示为float,但有可能接收到我发送的数据类型吗?

请在下面的代码示例中查看tkVariant案例:

class procedure TRTTI.SetObjPropValue(obj: TObject; rprop: TRttiProperty; value: OleVariant);
var
  rtyp: TRttiType;
  vt: TVarType;
begin
  if obj = nil then Exit();
  if (rprop <> nil) and (rprop.IsWritable) then begin
    case rprop.PropertyType.TypeKind of
      tkInteger, tkInt64:
        begin
          value := TVarConv.NullableCurr(value);
          if VarIsNumeric(value) then rprop.SetValue(obj, TValue.FromVariant(Trunc(value)));
        end;
      tkFloat:
        begin
          if rprop.PropertyType.Name = 'TDateTime' then
            value := TVarConv.NullableDateTime(value)
          else
            value := TVarConv.NullableFloat(value);
          if not VarIsNull(value) then rprop.SetValue(obj, TValue.FromVariant(value));
        end;
      tkChar, tkString, tkWChar, tkLString, tkWString, tkUString:
        begin
          rprop.SetValue(obj, TValue.FromVariant(VarToStr(value)));
        end;
      tkEnumeration:
        begin
          if rprop.PropertyType.Name = 'Boolean' then
            value := TVarConv.NullableBool(value)
          else
            value := null;
          if not VarIsNull(value) then rprop.SetValue(obj, TValue.FromVariant(value));
        end;
      tkVariant:
        //Here I transmit the TDateTime value
        rprop.SetValue(obj, TValue.FromVariant(value));
        //An object receives Float
    end;
  end;
end;
datetime delphi rtti variant
1个回答
5
投票

这里的问题是TValue.FromVariant在内部“解包”传递的Variant,将基础值存储在TValue中。在你的情况下,它正确地注意到TDateTime存储在Variant并存储为TDateTime

当你将包含TValue(属于TypeKind TDateTime)的tkFloat传递给SetValueTRttiProperty时,它会转换为属性类型Variant - 请参阅System.Rtti.Conv2Variant。这种方法忽略了一个事实,即tkFloat可以是TDateTime,但只是放置一个Variant存储浮点数到结果中。

解决方案很简单:不要使用TValue.FromVariant而只需使用TValue.From<Variant>(value)。这样您就可以将Variant值存储在TValue中并按原样传递,而不会对setter进行任何不必要的隐式类型转换。

报道为https://quality.embarcadero.com/browse/RSP-21176

© www.soinside.com 2019 - 2024. All rights reserved.