我試圖將一個型別為T的通用變數轉換成string。
TMyTest = class
class function GetAsString< T>(constAValue : T) : string; static;
end;
...
uses;
System.Rtti;
class function TMyTest. GetAsString<T>(const AValue : T) : string。
begin
結果 := TValue.From<T>(AValue).ToString()。
end。
使用幾種型別(如Integer, Double, Boolean...)效果很好,但使用Variant變數時 "失敗"。
procedure TForm1. FormCreate(Sender: TObject);。
var
Tmp : 變數。
begin
Tmp := 123;
ShowMessage(TMyTest.GetAsString<Variant>(Tmp))。
end;
它產生的輸出結果如下:
(variant)
我期望通過VarToStr函式獲得相同的輸出(但我不能對通用變數使用該函式):
123
uj5u.com熱心網友回復:
你可以檢查T是否是變體,然后在AsVariant函式上使用VarToStr。
你可以很容易地擴展該函式,以滿足其他型別的ToString不會給你預期的結果。
uses
System.TypInfo, System.Rtti;
class function TMyTest. GetAsString<T>(const AValue : T) : string。
begin
if PTypeInfo(TypeInfo(T)).Kind = tkVariant then
結果 := VarToStr(TValue.From<T> (AValue).AsVariant)
else[/span
結果 := TValue.From<T>(AValue).ToString()。
end;
uj5u.com熱心網友回復:
你可以使用RTTI檢查T的型別,然后當T是一個變數時呼叫VarToStr(),例如:
class function TMyTest. GetAsString<T>(const AValue : T) : string。
begin
if TypeInfo(T) = TypeInfo(Variant) then begin
//是的,下面的轉換看起來很奇怪,但編譯器無法驗證。
//T在這種情況下確實是一個變數,因為它對代碼進行了語法檢查。
//*在*實體化泛型之前,所以需要一個運行時的轉換。
///上面的TypeInfo檢查將確保轉換是安全的...。
Result := VarToStr({AValue}PVariant(@AValue)^) 。
end else begin
結果 := TValue.From<T>(AValue).ToString;
end。
end;
或者,在XE7 中,你可以使用GetTypeKind() 本質來代替:
class function TMyTest。 GetAsString<T>(const AValue : T) : string。
begin
if GetTypeKind(T) = tkVariant then begin
結果 := VarToStr({AValue}PVariant(@AValue)^) 。
end else begin
結果 := TValue.From<T>(AValue).ToString;
end。
end;
這兩種方法都允許編譯器通過從可執行檔案中洗掉未使用的分支來優化代碼,因為這兩種比較都被視為編譯時常量。
注意:
TValue.ToString不支持的其他TTypeKind值型別是tkUnknown, tkArray, tkRecord, 和tkDynArray。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/316505.html
標籤:
