Pau*_*aul 2 delphi datetime rtti variant
当我分配一个TDateTime值,以OleVariant使用RTTI的对象的属性,对象变为浮点值.
对象的设计使得此属性可以变为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;
Run Code Online (Sandbox Code Playgroud)
这里的问题TValue.FromVariant是内部"解包"传递的内容Variant,将底层值存储在内部TValue.在您的情况下,它正确地注意到a TDateTime存储在Variant并存储为TDateTime.
当你将TValue包含a TDateTime(属于TypeKind tkFloat)的那个传递给它SetValue时,TRttiProperty它会转换为属性的类型Variant- 见System.Rtti.Conv2Variant.这种方法忽略了一个事实,即a tkFloat可以是a TDateTime但只是简单地将Variant一个float存储到结果中.
解决方案很简单:不要使用TValue.FromVariant,只需简单TValue.From<Variant>(value).这样您就可以将Variant值存储在TValue中并按原样传递,而不会对setter进行任何不必要的隐式类型转换.
报告为https://quality.embarcadero.com/browse/RSP-21176
| 归档时间: |
|
| 查看次数: |
101 次 |
| 最近记录: |