程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> Delphi的TValue探索(一)

Delphi的TValue探索(一)

編輯:Delphi

TValue是Delphi的RTTI系統的重要類型。 經過摸索,發現TValue功能強大,可以實現很多功能。本文章中所有程序采用XE3運行通過。

一、TValue結構

TValue定義在System.Rtti.pas

TValue = ;

TValue提供了一些系列方法,幾乎都是操作FData.

TValueData描述如下:

  TValueData = //// FHeapData doubled  storage //  the     values: FTypeInfo couldn
    //// would be // FValueData  different: interfaces are always //  a reference   Integer 
      ;

TValueData是一個結構體,TValueData可以存儲任何類型的數據,經過TValue的方法可以與任何類型進行轉換:

TValue = // Low-level 
    Make(ABuffer: Pointer; ATypeInfo: PTypeInfo;  Result: TValue);   MakeWithoutCopy(ABuffer: Pointer; ATypeInfo: PTypeInfo;  Result: TValue);   Make(AValue: NativeInt; ATypeInfo: PTypeInfo;  Result: TValue); // Low-level 
   DataSize: Integer // If internal data  something // reference  *without*;

通過調用Make(...),將任意類型數據轉換為TValue
通過調用ExtractRawData(...), ExtractRawDataNoCopy(...)將TValue轉換為任意數據類型,兩者區別是ExtractRawDataNoCopy轉換時在堆中申請內存的數據,而ExtractRawData是安全的。
GetReferenceToRawData返回數據的指針,也是堆內存的指針。

二、類型轉換為TValue

下面例子測試Integer和TRect:

  
  
 
   
   
 
   IntData :=    TValue.Make(@IntData,TypeInfo(Integer),IntValue); //Integer類型也可以直接調用 IntValue :=    RecData.Left :=    RecData.Right :=     .
)

三、TValue轉換到類型

在反序列化(反持久化)時,如果知道數據類型,可以調用下面的方法生成一個與此類型相應的TValue空記錄:

TValue.Make(,TypeInfoVar,OutputTValue);

通過ExtractRawData,可以將TValue數據直接轉換某類型數據:

  
  
 
    
 
   RecData.Left :=    RecData.Right :=    TValue.Make(@RecData,TypeInfo(TRect),RecValue);    // 
   RecValue.ExtractRawData(@RecDataOut);    //   
  .


四、通過TValue的訪問類型的成員變量

TValue轉換自某個類型後,可以使用的GetReferenceToRawData()獲取數據指針,通過調用SetValue和GetValue讀寫
某個成員的值。

  
  
 
    
 
   Ctx :=   //   TValue.Make(   //   Ctx.GetType(TypeInfo(TRect)).GetField().SetValue(RecValue.GetReferenceToRawData,   Ctx.GetType(TypeInfo(TRect)).GetField().SetValue(RecValue.GetReferenceToRawData,   //      .


五、泛型轉換函數

我們上面的例子,通過調用Make函數來轉換成TValue,以及通過ExtractRawData轉換成需要的類型,
Delphi還提供了泛型轉換函數,可以指定已知的類型,直接進行轉換:

  From<T>( AsType<T> IsType<T> TryAsType<T>( Cast<T>: TValue; ;

看下面的例子:

  
  
 
    
   RecData.Left :=    RecData.Right :=  
   RecValue := TValue.From<TRect>(RecData);        // 
   Writeln(RecValue.IsType<TRect> 
   RecDataOut := RecValue.AsType<TRect>;            // 
    .


六、數組

如果TValue轉換自數組類型,則可以調用一下方法:

 SetArrayElement(Index: Integer;  AValue: TValue);

如果用下面的方式定義數組,則不支持轉換到TValue:

  Integer;

我可以先定義數組類型後,再定義變量,則可以轉換到TValue:

=  //<Integer>; //在 System.pas 定義:   TArray<T> =   T;

七、Variant

Variant與TValue的轉換容易產生混淆,調用TValue.FromVariant(),並不是將Varaint轉換為TValue:

  
  
 
   
   vExample :=    Value := TValue.FromVariant(vExample);    //
   
   vExample :=    Value :=   
  .
Hello World

如果希望將Variant轉換為TValue,可以使用這個方法:

  
  
 
   
   vExample :=    Value := TValue.From<>    Writeln(value.AsType<variant> 
   vExample :=    Value := TValue.From<>    Writeln(value.AsType<variant> 
  .
Hello World

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved