2011-10-06 16 views
6

मैं धाराप्रवाह विस्तार विधियों के साथ प्रयोग कर रहा हूं।मूल्य प्रकारों के साथ सामान्य बाधाओं का उपयोग

मेरे पास सुरक्षित कास्ट करने के लिए निम्न सरल एक्सटेंशन विधि है।

 public static T As<T>(this Object source) 
     where T : class 
    { 
     return source as T; 
    } 

यह अच्छी तरह से काम, लेकिन जब मैं यह सहज ज्ञान युक्त एक अधिभार

 public static T As<T>(this ValueType source) 
     where T : struct 
    { 
     return (T)source; 
    } 

साथ valuetypes उपयोग करने के लिए करने की कोशिश की मैं समस्याओं में भाग गया। विधि संकल्प तर्क हमेशा ऊपर की पहली विधि चुनता है, और एक वाक्यविन्यास त्रुटि (सटीक) देता है कि संरचना कक्षा नहीं है।

क्या उपरोक्त को संभालने का कोई तरीका है, या क्या मुझे उसी विधि में सभी प्रकार के परीक्षण और संचालन के दौरान बाधा को हटाने का मार्ग जाना चाहिए?

==== संपादित करें: सवालों के जवाब देने ====

मैं 3.5 ढांचे के खिलाफ इस संकलन कर रहा हूँ। मैं वास्तव में कुछ भी हासिल करने की कोशिश नहीं कर रहा हूं; यह उपर्युक्त के साथ सिर्फ एक प्रयोग है। मेरी रुचि पिक्चर की गई थी और मैंने कुछ कोड एक साथ फेंक दिया।

मैं विशेष रूप से इसके साथ 'सुरक्षित' कलाकार शेष नहीं हूं। इस तरह यह शुरू हुआ, और डिफ़ॉल्ट() के साथ सुरक्षित रखा जा सकता है - लेकिन यह वास्तव में 'सुरक्षितता' सुनिश्चित करने के लिए प्रश्न और कोड का ध्यान नहीं है।

अभिव्यक्ति के रूप में, value.As<int>()(int)value से अधिक अभिव्यक्तिपूर्ण नहीं है; लेकिन विधि के उपयोगकर्ता को 'बस पता' क्यों होना चाहिए, यह केवल संदर्भ प्रकारों के साथ काम करता है? मैं इसे काम करने की कोशिश कर रहा हूं अभिव्यक्तिपूर्ण लेखन की तुलना में विधि के अपेक्षित व्यवहार के बारे में अधिक था।

कोड स्निपेट value.As<DateTime>(), त्रुटि देता है "प्रकार" सिस्टम। डेटाटाइम 'सामान्य प्रकार या विधि में पैरामीटर' टी 'के रूप में उपयोग करने के लिए एक संदर्भ प्रकार होना चाहिए .... जैसा कि (ऑब्जेक्ट) " । त्रुटि संदेश से मैं देखता हूं कि यह ऊपर की शीर्ष विधि का उपयोग करने का संकल्प कर रहा है क्योंकि इसे संदर्भ प्रकार की आवश्यकता है।

+0

सी # किस संस्करण की तुलना में उपयोग करने के लिए आसान है आप उपयोग कर रहे? .NET 4 में, दूसरा अधिभार चुना जाता है। –

+1

क्या आपका मतलब है 'ऑब्जेक्ट ओ = 42; var i = o.As (); 'यह वाक्यविन्यास त्रुटि देता है? या आप सही कोड दिखा सकते हैं जो इसे देता है? – svick

+0

@ svick की टिप्पणी शायद मेरे दिमाग में लाती है, उदाहरण के लिए, डेटाबेस डेटाबेस के साथ ऐसा करने की कोशिश कर रहा है, उदाहरण के लिए। यदि ऐसा है, तो पंक्ति में ऑब्जेक्ट मान को उचित प्रकार में बदलने के लिए एक एक्सटेंशन विधि पहले से मौजूद है। [फ़ील्ड ] (http://msdn.microsoft.com/en-us/library/bb360891.aspx) –

उत्तर

3

.NET 4 में, दूसरा अधिभार आपके कोड नमूने के आधार पर चुना जाता है। (इसके अलावा सिर्फ .NET 3.5 के विरुद्ध परीक्षण किया गया, उसी परिणाम।)

int myInt = 1; 
long myLong = myInt.As<long>(); // chooses ValueType version 

हालांकि, यह केवल हमें अगले दुर्घटना के दृश्य में ले जाता है। (T)source; परिणामस्वरूप एक अवैध कास्ट अपवाद है। आप कि के रूप में

public static T As<T>(this ValueType source) 
    where T : struct 
{ 
    return (T)Convert.ChangeType(source, typeof(T)); 
} 

हालांकि विधि लिख कर चारों ओर हो सकता है, मुझे आश्चर्य है कि क्या आप वास्तव में प्राप्त करने के लिए के रूप में मैं तत्काल लाभ नहीं दिख रहा है देख रहे हैं। (और उस बात के लिए, यह नहीं सुरक्षितsource as T वस्तु संस्करण की तरह है।) उदाहरण के लिए, कैसे

long myLong = myInt.As<long>(); 

किसी भी अधिक अर्थपूर्ण या

long myLong = (long)myInt; 
+0

चूंकि वैल्यू टाइप है - इसके नाम के बावजूद - वास्तव में एक वर्ग प्रकार, बाद के फॉर्मूलेशन के लिए मुक्केबाजी की आवश्यकता होगी तर्क। दुर्भाग्यवश, मुझे सच में नहीं लगता कि .NET को सामान्य पैरामीटर के मान-प्रकार-नेस के आधार पर ओवरलोडिंग करने का कोई तरीका है। – supercat

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