如何确定非对象泛型的类型?

时间:2013-10-03 16:51:23

标签: delphi generics

显然以下代码不起作用:

....
property value: T read FTheValue;
....
function TDefiniteValue<T>.toString: string;
begin
  Result:= ' definitly ';
  if (value is TObject) then Result:= Result + TObject(value).ToString
  else if (value is integer) then Result:= Result + IntToStr(integer(value));
  //                ^^^^^^^
  //                +++++++-- integer is not an object
end;

如何比较非对象的类型?

这是一个SSCCE

Program Maybe; 

interface

uses
  System.Generics.Collections, System.SysUtils;

type    
  TDefiniteValue<T> = class(TEnumerable<T>)
  strict private
    FTheValue: T;
  strict protected
    function toString: string; override;
    property value: T read FTheValue;
  end;

implementation

function TDefiniteValue<T>.toString: string;
begin
  Result:= ' definitly ';
  if (value is TObject) then Result:= Result + TObject(value).ToString
  else if (value is integer) then Result:= Result + IntToStr(integer(value));
  //                ^^^^^^^
  //                +++++++-- integer is not an object.
end;

begin
end.

2 个答案:

答案 0 :(得分:5)

只需使用System.Rtti.TValue

function TDefiniteValue<T>.ToString: string;
var
  v: TValue;
begin
  v := TValue.From<T>(FTheValue);
  Result:= ' definitly ' + v.ToString;
end;

答案 1 :(得分:3)

DSharp有一个单位就是这个目的,这里是链接:

https://code.google.com/p/delphisorcery/source/browse/trunk/Source/Core/DSharp.Core.Reflection.pas

它包含Rtti的类帮助程序列表。这允许您询问您的对象。

相关部分如下:

TValue = Rtti.TValue;

{$REGION 'Documentation'}
/// <summary>
/// Extends <see cref="Rtti.TValue">TValue</see> for easier RTTI use.
/// </summary>
{$ENDREGION}
TValueHelper = record helper for TValue
private
function GetRttiType: TRttiType;
class function FromFloat(ATypeInfo: PTypeInfo; AValue: Extended): TValue; static;
public
function IsFloat: Boolean;
function IsNumeric: Boolean;
function IsPointer: Boolean;
function IsString: Boolean;

function IsInstance: Boolean;
function IsInterface: Boolean;

// conversion for almost all standard types
function TryConvert(ATypeInfo: PTypeInfo; out AResult: TValue): Boolean; overload;
function TryConvert<T>(out AResult: TValue): Boolean; overload;

function AsByte: Byte;
function AsCardinal: Cardinal;
....