2011-10-25 12 views
6

यहाँ एक टुकड़ा दिखा मैं क्या हासिल करने की कोशिश कर रहा हूँ:प्रकार <T> प्रकार वैरिएंट में कनवर्ट करना, क्या यह संभव है?

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; 

मुझे पता है कि समान किरदार के साथ ऊपर apporach अनुभवहीन है, लेकिन मुझे आशा है कि आप विचार मिलता है। मैं इसे कुछ रूपांतरण तंत्र से बदलना चाहता हूं।

टीएमओब्जेक्ट हमेशा इंटीजर, स्ट्रिंग, सिंगल, डबल जैसे सरल प्रकार का होगा।

इस तरह के रूपांतरण का उद्देश्य यह है कि वर्ट टाइप मुझे प्रत्येक साधारण प्रकार के लिए पूर्णांक स्थिर देता है जिसे मैं कहीं और स्टोर कर सकता हूं।

मैं जानना चाहता हूं कि ऐसा रूपांतरण संभव है या नहीं?

आपके समय के लिए धन्यवाद।

उत्तर

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 
1

मैं नहीं देख सकता कि जेनेरिक के साथ ऐसा करना संभव कैसे हो सकता है। कंपाइलर को यह जानने की आवश्यकता है कि T प्रकार का उदाहरण किसी भी T के लिए Variant पर असाइन किया जा सकता है। आपके लिए संभव है कि संकलक को बताने का कोई तरीका नहीं है।

यदि यह सी ++ में टेम्पलेट थे तो यह छोटा होगा।

+0

+1, मैं सी ++ डेल्फी ... –

+0

में टेम्पलेट्स के लिए लंबे समय @ सेठ मुझे नहीं पता था कि आप एक डेल्फी उपयोगकर्ता थे। मैंने हमेशा आपको घुंघराले ब्रेसिज़ के रूप में नीचे रखा था! –

+1

आमतौर पर लेकिन विशेष रूप से नहीं। मैं डेल्फी को सी # के मूल-निष्पादन योग्य-उत्पन्न संस्करण के रूप में उपयोग करता हूं (खड़ा नहीं हो सकता ऑनलाइन असेंबली का उपयोग करने में सक्षम होने के नाते) और इसे बहुत पसंद है। –

1

धन्यवाद लोग आपके उत्तरों के लिए:

जैसा कि @RRUZ ने दिखाया है कि यह possib है ले (मेरा मतलब सख्त आकलन नहीं है बल्कि डेटा के प्रकार को निकालने का मतलब है)। मैं किसी भी उत्तर की प्रतीक्षा करते समय अपने आप पर काम कर रहा था और एक और सामान्य समाधान मिला है।

तो मैं इसे यहाँ positing हूँ:

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; 

एक बार फिर धन्यवाद!

+1

मूल्य पास करने की आवश्यकता नहीं है, आप इसे सीधे टी –

+0

से पढ़ सकते हैं। क्या कोई संकेत है कि 'varType' में 'TypeInfo (T) मान्य मान होता है। दयालु है 'tkDynArray' नहीं? या 'varType' में संग्रहीत पूर्णांक वास्तव में एक' टीवीर टाइप 'मान है, क्योंकि गतिशील सरणी उन चीज़ों को पकड़ सकती है जो' वेरिएंट 'नहीं कर सकती हैं? मुझे नहीं लगता कि या तो जरूरी सच है। –

+0

@RobKennedy मुझे डर है कि आपको सही है। मुझे नहीं लगता कि यह उम्मीद के रूप में क्यों काम नहीं कर रहा है।यह एक शर्म की बात है ... – Wodzu

7

यह आरटीटीआई (2010 और नए) के साथ डेल्फी में मामूली रूप से हल करने योग्य है। बहुत बुरा आप 2009 तक ही सीमित रहते हैं :(

function TMyObject<T>.GetVarType(Value: T): TVarType; 
begin 
    Result := VarType(TValue.From<T>(Value).AsVariant); 
end; 

यह सरल प्रकार के लिए ही काम करता है, लेकिन यह एक बाधा प्रश्न में निर्दिष्ट किया गया था।

+0

धन्यवाद @ gabr जब मैं D2010 पर स्विच करता हूं तो यह निश्चित रूप से सहायक होगा :) – Wodzu

संबंधित मुद्दे

 संबंधित मुद्दे