Mat*_*erg 12 delphi generics rtti variant delphi-xe
我有一个Delphi泛型类,它使用泛型类型的参数公开一个函数.在这个函数中,我需要将泛型类型的实例传递给另一个期望Variant类型的对象.与此类似:
type
IMyInterface = interface
DoStuff(Value: Variant);
end;
TMyClass<T> = class
FMyIntf: IMyInterface
procedure DoStuff(SomeValue: T);
end;
[...]
procedure MyClass<T>.DoStuff(SomeValue: T);
begin
FMyIntf.DoStuff((*convert SomeValue to Variant here*));
end;
Run Code Online (Sandbox Code Playgroud)
我尝试使用Rtti.TValue.From(SomeValue).AsVariant.这适用于整体类型,但对布尔人来说却是爆炸性的.我不太明白为什么,因为通常我能够为Variant分配一个布尔值...
有没有更好的方法进行此转换?我只需要它用于简单的内置类型(不包括枚举和记录)
Lin*_*nas 10
我认为没有直接的方法将泛型类型转换为变体,因为变体不能容纳所有可能的类型.您必须编写特定的转换例程.例如:
interface
//...
type
TDemo = class
public
class function GetAsVariant<T>(const AValue: T): Variant;
end;
//...
implementation
uses
Rtti,
TypInfo;
//...
{ TDemo}
class function TDemo.GetAsVariant<T>(const AValue: T): Variant;
var
val: TValue;
bRes: Boolean;
begin
val := TValue.From<T>(AValue);
case val.Kind of
tkInteger: Result := val.AsInteger;
tkInt64: Result := val.AsInt64;
tkEnumeration:
begin
if val.TryAsType<Boolean>(bRes) then
Result := bRes
else
Result := val.AsOrdinal;
end;
tkFloat: Result := val.AsExtended;
tkString, tkChar, tkWChar, tkLString, tkWString, tkUString:
Result := val.AsString;
tkVariant: Result := val.AsVariant
else
begin
raise Exception.Create('Unsupported type');
end;
end;
end;
Run Code Online (Sandbox Code Playgroud)
因为TValue.AsVariant
内部处理大多数类型转换,所以可以简化此功能.我将处理枚举,以防您以后需要它们:
class function TDemo.GetAsVariant<T>(const AValue: T): Variant;
var
val: TValue;
begin
val := TValue.From<T>(AValue);
case val.Kind of
tkEnumeration:
begin
if val.TypeInfo = TypeInfo(Boolean) then
Result := val.AsBoolean
else
Result := val.AsOrdinal;
end
else
begin
Result := val.AsVariant;
end;
end;
Run Code Online (Sandbox Code Playgroud)
可能的用法:
var
vValue: Variant;
begin
vValue := TDemo.GetAsVariant<Boolean>(True);
Assert(vValue = True); //now vValue is a correct Boolean
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3399 次 |
最近记录: |