2010-11-03 30 views
111

में परिवर्तित नहीं किया जा सकता है यह संभवतः एक नौसिखिया प्रश्न है, लेकिन Google ने आश्चर्यजनक रूप से उत्तर नहीं दिया।प्रकार 'टी' का मूल्य

मैं इस बल्कि कृत्रिम विधि

T HowToCast<T>(T t) 
    { 
     if (typeof(T) == typeof(string)) 
     { 
      T newT1 = "some text"; 
      T newT2 = (string)t; 
     } 

     return t; 
    } 

एक सी से आ ++ पृष्ठभूमि मैं यह काम करने की उम्मीद कर दिया है। हालांकि, यह उपरोक्त असाइनमेंट दोनों के लिए "स्ट्रिंग में टाइप 'टी' को पूर्ण रूप से रूपांतरित नहीं कर सकता है" और "प्रकार को परिवर्तित नहीं कर सकता" टी को स्ट्रिंग में परिवर्तित नहीं कर सकता है।

मैं या तो कुछ अवधारणात्मक गलत कर रहा हूं या सिर्फ गलत वाक्यविन्यास है। कृपया इसे हल करने में मेरी मदद करें।

धन्यवाद!

+14

IMO आप अपनी जेनरिक कोड में प्रकार की जाँच कर रहे हैं तो जेनरिक शायद करने के लिए सही समाधान नहीं कर रहे हैं अपने मुसीबत। –

+0

अभिव्यक्ति 'टाइपोफ (टी) == टाइपोफ (स्ट्रिंग)' को रनटाइम पर हल किया गया है, संकलित समय नहीं। इस प्रकार ब्लॉक में निम्न पंक्ति अमान्य है। –

+6

(टी) कनवर्ट करें।चेंजटाइप (नया टी 1, टाइपोफ (टी)) – vsapiha

उत्तर

218

भले ही यह if ब्लॉक के अंदर है, संकलक को पता नहीं है कि Tstring है।
इसलिए, यह आपको कास्ट करने नहीं देता है। और वहां से string को

आप object, (जो किसी भी T पर कास्ट कर सकते) को कास्ट करने के लिए की जरूरत है (एक ही कारण है कि आप DateTimestring पर कास्ट नहीं कर सकते हैं) (object के बाद से string लिए डाली जा सकती है)।
उदाहरण के लिए:

T newT1 = (T)(object)"some text"; 
string newT2 = (string)(object)t; 
+2

यह काम करता है! मैं दूसरा अनुमान लगा रहा हूं जैसे टी newT2 = (टी) (ऑब्जेक्ट) टी होना चाहिए; हालांकि यह कोई ओप नहीं है। – Alex

+2

अतिरिक्त: सी ++ टेम्पलेट अनिवार्य रूप से प्रतिस्थापित सही मूल्यों के साथ संकलन समय पर कट-एंड-पेस्ट हैं। सी # में वास्तविक जेनेरिक टेम्पलेट (इसका "तात्कालिकता" नहीं है) संकलन के बाद मौजूद है और इस प्रकार निर्दिष्ट प्रकार सीमाओं में सामान्य (पन क्षमा करें) सामान्य होना चाहिए। –

+0

(स्ट्रिंग) (ऑब्जेक्ट) टी; यद्यपि यहां कुछ भी नहीं है, साथ ही इसे छोड़कर, (स्ट्रिंग) (ऑब्जेक्ट) जो – Doggett

8

दोनों लाइनों एक ही समस्या

T newT1 = "some text"; 
T newT2 = (string)t; 

संकलक नहीं जानता है कि टी एक स्ट्रिंग है और इतना है कि आवंटित करने के लिए कैसे जानने का कोई तरीका नहीं है है। लेकिन जब से तुम तुम सिर्फ

T newT1 = "some text" as T; 
T newT2 = t; 

साथ यह मजबूर कर सकते हैं आप भी बाधा जोड़ने की जरूरत है यह पहले से ही एक स्ट्रिंग है, क्योंकि टी कास्ट करने के लिए की जरूरत नहीं है, जाँच की

where T : class 
+2

गलत। यह संकलित नहीं होगा। मेरा जवाब देखें – SLaks

+1

संकलित बस ठीक है (जहां से है, जोड़ा गया है कि मैंने पोस्ट करने के कुछ सेकंड बाद, इसे याद किया होगा)। ओह एनएम – Doggett

1

यदि आप स्पष्ट प्रकारों की जांच कर रहे हैं, आप उन चर को T के रूप में क्यों घोषित कर रहे हैं?

T HowToCast<T>(T t) 
{ 
    if (typeof(T) == typeof(string)) 
    { 
     var newT1 = "some text"; 
     var newT2 = t; //this builds but I'm not sure what it does under the hood. 
     var newT3 = t.ToString(); //for sure the string you want. 
    } 

    return t; 
} 
+4

कास्ट बदलने के लिए भूल गया दूसरी पंक्ति प्रकार 'टी' प्रकार का एक चर बनाता है। – SLaks

+0

आप पूछते हैं कि प्रकार की जांच क्यों करें? मान लीजिए कि आपके पास बेस फ़ील्ड प्रकार है जो 'ऑब्जेक्ट' मानों को संग्रहीत करता है, जो व्युत्पन्न प्रकारों के साथ 'स्ट्रिंग' मान संग्रहीत करता है। मान लीजिए कि इन फ़ील्ड में "DefaultIfNotProvided" मान भी नहीं है, इसलिए आपको यह जांचने की आवश्यकता है कि उपयोगकर्ता द्वारा प्रदत्त मान (जो ऑब्जेक्ट या स्ट्रिंग या यहां तक ​​कि एक संख्यात्मक आदिम हो सकता है) 'डिफ़ॉल्ट (टी)' के बराबर है। स्ट्रिंग को एक विशेष मामले के रूप में माना जा सकता है जहां एक खाली/सफेद जगह स्ट्रिंग को डिफ़ॉल्ट (टी) के समान माना जाता है, ताकि आप यह जांचना चाहें कि 'टी उपयोगकर्ता वैल्यू; var isBlank = (userValue स्ट्रिंग है) && String.IsNullOrWhitespace (उपयोगकर्ता वैल्यू स्ट्रिंग के रूप में); '। – Triynko

-2

बदलें इस लाइन:

if (typeof(T) == typeof(string)) 

इस लाइन के लिए:

if (t.GetType() == typeof(string)) 
+1

वे वही हैं – bigworld12

0

आप भी इस त्रुटि अगर आप दोनों अपने वर्ग और अपने विधि के लिए एक सामान्य घोषणा की है मिल जाएगा। उदाहरण के लिए नीचे दिखाया गया कोड इस संकलन त्रुटि देता है।

public class Foo <T> { 

    T var; 

    public <T> void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException { 
     this.var = cls.newInstance(); 
    } 

} 

इस कोड (नोट टी विधि घोषणा से हटा) संकलित करता है:,,

public class Foo <T> { 

    T var; 

    public void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException { 
     this.var = cls.newInstance(); 
    } 

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