这是一个片段,展示了我想要实现的目标:
type
TMyObject<T> = class (TObject)
function GetVarType(Value: T): TVarType;
end;
function TMyObject<T>.GetVarType(Value: T): TVarType;
var
TmpValue: Variant;
begin
TmpValue := Variant(Value); //Invalid typecast
Result := VarType(TmpValue);
end;
我知道上面提到的使用类型转换是天真的,但我希望你能得到这个想法。我想用一些转换机制替换它。
TMyObject将始终是简单类型,如Integer,String,Single,Double。
这种转换的目的是函数VarType为每个我可以存储在其他地方的简单类型提供整数常量。
我想知道这种转换是否可行?
感谢您的时间。
答案 0 :(得分:7)
在Delphis中,通过增强的RTTI(2010及更新版本)可以轻松解决这个问题。太糟糕了,你只限于2009年:(
function TMyObject<T>.GetVarType(Value: T): TVarType;
begin
Result := VarType(TValue.From<T>(Value).AsVariant);
end;
这仅适用于简单类型,但这是问题中指定的约束。
答案 1 :(得分:6)
您可以使用RTTI获取此信息,只需检查TTypeInfo.Kind
属性的值:
检查此示例代码
{$APPTYPE CONSOLE}
uses
TypInfo,
Variants,
Generics.Collections,
SysUtils;
type
TMyObject<T> = class (TObject)
function GetVarType(Value: T): TVarType;
end;
function TMyObject<T>.GetVarType(Value: T): TVarType;
begin
Case PTypeInfo(TypeInfo(T))^.Kind of
tkInteger : Result:=varInteger;
tkFloat : Result:=varDouble;
tkString : Result:=varString;
tkUString : Result:=varUString;
//add more types here
End;
end;
Var
LObj : TMyObject<Integer>;
begin
try
Writeln(VarTypeAsText(TMyObject<Integer>.Create.GetVarType(5)));
Writeln(VarTypeAsText(TMyObject<String>.Create.GetVarType('Test')));
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
Readln;
end.
这将返回
Integer
UnicodeString
答案 2 :(得分:1)
我看不出如何用泛型做到这一点。编译器需要知道可以为任何可能的T
将Variant
类型的实例分配给T
。你没办法告诉那个编译器是可能的。
如果这是C ++中的模板,那么它将是微不足道的。
答案 3 :(得分:1)
谢谢你的回答:
正如@RRUZ所示,它是可能的(我的意思是不是严格的分配,而是提取数据的类型)。我在等待任何答案的同时独自工作,并找到了更通用的解决方案。
所以我在这里定位:
type
TMyObject<T> = class (TObject)
function GetVarType(Value: T): TVarType;
end;
function TMyObject<T>.GetVarType(Value: T): TVarType;
begin
Result := GetTypeData(TypeInfo(T)).varType;
end;
再次感谢!