下面是一个片段,显示了我想要实现的目标:
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为每个简单类型提供整型常量,我可以将其存储在其他地方。
我想知道这种转换是否可能?
感谢您的宝贵时间。
在delphi中使用增强的RTTI(2010及更新版本)很容易解决。可惜你仅限于2009年:
function TMyObject<T>.GetVarType(Value: T): TVarType;
begin
Result := VarType(TValue.From<T>(Value).AsVariant);
end;
这只适用于简单类型,但这是问题中指定的约束。
您可以使用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
我不明白用泛型怎么可能做到这一点。编译器需要知道类型T
的实例可以分配给任何可能的T
的Variant
。你没有办法告诉编译器这是可能的。
如果这是c++中的模板,那么它将是微不足道的。
谢谢大家的回答:
正如@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;
再次感谢!