【问题标题】:TValue.AsType<T> with enum types in DelphiTValue.AsType<T> 在 Delphi 中具有枚举类型
【发布时间】:2019-05-26 07:33:11
【问题描述】:

用 Delphi 编写

uses System.Classes;
...
var
  A: TAlignment;
  Value: TValue;
begin
  Value := 0;
  A := Value.AsType<TAlignment>();
end;

在 AsType 引发 EInvalidCast。

有没有办法使用 TValue 从整数值转换为任何枚举类型?

这当然是显而易见的答案:

A := TAlignment(Value);

但我希望提供一个也适用于其他类型的通用函数。

【问题讨论】:

  • 查看TValue.FromOrdinal。您的示例试图使用 TValue 转换类型,这并不是 TValue 的真正用途。
  • 好吧,在我的例子中,'Value := 0' 部分实际上是给出的 - 实际问题是转换。我可以把它留给硬演员,这不是那么明显,所以我想启用 AsType 或类似的东西。这就是最初让我想到这个的原因:stackoverflow.com/questions/52946989/…
  • 我认为强制转换是非法的,因此是错误的。我个人使用我的辅助类型进行此类转换。使用 TValue 似乎太重了。
  • @DavidHeffernan 是的,我也是这么想的。但如果可能的话,我仍然想以某种方式启用它。
  • 你每次都会得到异常。我会避免使用 TValue 并使用通用的帮助器类型来做你需要的事情。 Spring4D中有一个例子。

标签: delphi enums tvalue


【解决方案1】:

这似乎可以做到:

  if (PTypeInfo(TypeInfo(TAlignment))^.Kind = tkEnumeration) and (Value.TypeInfo.Kind = tkInteger ) then
    case System.TypInfo.GetTypeData(TypeInfo(TAlignment))^.OrdType of
      otUByte, otSByte: PByte(@A)^ := Value.AsInteger;
      otUWord, otSWord: PWord(@A)^ := Value.AsInteger;
      otULong, otSLong: PInteger(@A)^ := Value.AsInteger;
    end
  else
    A := Value.AsType<TAlignment>();

其中 TAlignment 在泛型函数中也可以是 T。

(从 TRttiEnumerationType.GetValue 复制的想法)

【讨论】:

猜你喜欢
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多