2010-03-25 22 views
7

पर कनवर्ट करें मैं इसे प्राप्त करके मौजूदा .NET फ्रेमवर्क क्लास को विस्तारित कर रहा हूं। मैं मूल प्रकार की ऑब्जेक्ट को व्युत्पन्न प्रकार में कैसे परिवर्तित करूं?कन्वर्ट/कास्ट प्रकार को व्युत्पन्न प्रकार

public class Results { //Framework methods } 

public class MyResults : Results { //Nothing here } 

//I call the framework method 

public static MyResults GetResults() 
{ 
    Results results = new Results(); 
    //Results results = new MyResults(); //tried this as well. 

    results = CallFrameworkMethod(); 

    return (MyResults)results; //Throws runtime exception 
} 

मैं समझता हूँ कि ऐसा होता है के रूप में मैं एक व्युत्पन्न प्रकार के लिए एक आधार के प्रकार कास्ट करने के लिए कोशिश कर रहा हूँ और अगर व्युत्पन्न प्रकार अतिरिक्त गुण है, तो स्मृति आवंटित नहीं किया गया है। जब मैं अतिरिक्त गुण जोड़ता हूं, तो मुझे परवाह नहीं है कि क्या उन्हें शून्य में प्रारंभ किया गया है।

मैन्युअल प्रतिलिपि किए बिना मैं इसे कैसे कर सकता हूं?

+1

इस प्रकार को विस्तारित करने के बजाय आप केवल एक एक्सटेंशन विधि बना सकते हैं? –

+0

यह एक अच्छा विचार है। विस्तार विधियों के साथ, मैं नई विधियों को संलग्न कर सकता हूं। मैं वास्तव में प्रकार के लिए अतिरिक्त गुण/चर जोड़ नहीं सकता। – Nick

+0

यह एक साधारण प्रतिलिपि निर्माता लिखने से बचने के लिए बहुत सारे काम की तरह लगता है। मुझे कई मामलों में पता है जो संभव नहीं है, लेकिन यह इस मामले में एक संभावित समाधान की तरह लगता है। – overslacked

उत्तर

11

आप नहीं कर सकते हैं । यदि resultsMyResults (उदाहरण के लिए CallFrameworkMethod आधार Results उदाहरण देता है) का संदर्भ नहीं देता है, तो कास्टिंग इसे ऐसा नहीं करेगा: आपको मौजूदा गैर-MyResults के आधार पर एक नया MyResults बनाना होगा। कास्टिंग संदर्भित वस्तु के ठोस प्रकार को बदलने के बारे में नहीं, संदर्भ के संकलन-समय प्रकार को बदलने के बारे में है।

आप नए MyResults वस्तु की initialisation के साथ मदद करने के लिए इस तरह के प्रतिबिंब या AutoMapper के रूप में उपकरण का उपयोग कर सकते हैं - लेकिन एक नए MyResults वस्तु, वहाँ होना चाहिए क्योंकि आप एक आधार Results वस्तु नहीं बता सकता एक MyResults वस्तु बन जाते हैं।

+0

क्या इसे भिन्नता/कॉन्वर्सिस के साथ करना है? मैं .NET 4.0 पर हूं और मुझे पता है कि उन्होंने भिन्नता/कॉन्वर्सिस के लिए कुछ किया है। कोई उपाय? – Nick

+0

नहीं, सी # 4.0 भिन्नता जब आप मूल/व्युत्पन्न प्रकारों का उपयोग जेनेरिक इंटरफेस या प्रतिनिधियों के लिए प्रकार पैरामीटर के रूप में करते हैं; और आपके पास यहां कोई सामान्य इंटरफेस या प्रतिनिधि नहीं हैं। आपकी समस्या अधिक मौलिक है: यह वस्तु के ठोस प्रकार के बारे में है। एक परिणाम ऑब्जेक्ट बस * MyResults प्रकार का एक उदाहरण नहीं है। यदि CallFrameworkMethod एक (वास्तविक) परिणाम देता है, तो उस ऑब्जेक्ट के संदर्भ * को MyResults में नहीं डाला जा सकता है क्योंकि ऑब्जेक्ट * एक MyResults नहीं है। इसके आस-पास एकमात्र तरीका है MyFesults को वापस करने के लिए, या एक नया MyResults बनाने के लिए CallFrameworkMethod को बदलना। – itowlson

+0

भिन्नता आपको यहां मदद नहीं करेगा –

1

कैसे के बारे में:

... 
MyResults results = new MyResults(); 
... 

और तुम शायद भी अपने MyResults कक्षा में एक निर्माता बनाने की जरूरत:

public class MyResults : Results 
{ 
    public MyResults() : base() {} 
} 

वास्तव में क्या "यहाँ कुछ भी नहीं" का अर्थ है?

संपादित

results = (CallFrameworkMethod() as MyResults); 

यह does not अपवाद है, लेकिन यह आप के लिए उपयोगी हो सकता है अगर - यह आप आगे क्या करना चाहते हैं क्या पर निर्भर करता है ...

+0

"यहां कुछ भी नहीं" जैसा सचमुच कुछ भी नहीं है। अभी के लिए, मुझे भविष्य में – Nick

+0

में नए गुण जोड़ने के इरादे से मूल प्रकार से विरासत मिली है। मैंने अपना जवाब संपादित किया - कृपया नया समाधान देखें। – Gacek

+0

@Gacek - कीवर्ड के रूप में उपयोग करना अपवाद नहीं फेंकता है लेकिन MyResult ऑब्जेक्ट शून्य है हालांकि CallFrameworkMethod एक गैर शून्य ऑब्जेक्ट देता है। – Nick

0
Results results = new MyResults(); 
    ... 

return (MyResults)results; 

काम करना चाहिए। यदि नहीं, तो समस्या कहीं और है।

+1

नहीं, क्योंकि वह कॉलफ्रेमवर्क मोड के वापसी मूल्य के साथ इसे ओवरराइट करता है - जो शायद मायरसल्ट के अलावा कुछ और लौट रहा है, या कलाकार सफल होगा। – itowlson

+0

CallFrameworkMethod() प्रकार का ऑब्जेक्ट देता है परिणाम – Nick

+0

वह MyResult क्लास का एक उदाहरण बनाता है और फिर CallFrameworkMethod विधि को कॉल करता है जो परिणाम ऑब्जेक्ट को किसी अन्य उदाहरण को निर्दिष्ट करता है जिसे जाया नहीं जा सकता है। – Machta

1

नहीं, आप व्युत्पन्न प्रकार के उदाहरण में सामग्री को कॉपी करने से नहीं बच सकते हैं। खैर, अगर आप एक सामान्य विधि होने के लिए CallFrameworkMethod को बदल सकते हैं, और MyResults में शून्य-तर्क कन्स्ट्रक्टर है, तो CallFrameworkMethod आपके व्युत्पन्न प्रकार का एक नया उदाहरण सीधे बना सकता है, फिर केवल मूल प्रकार के सदस्यों का उपयोग करें।

लेकिन शायद आपको एक नई वस्तु पर प्रतिलिपि बनाना होगा। याद रखें कि इस प्रतिलिपि कोड को निश्चित रूप से किसी अन्य विधि में पुन: उपयोग किया जा सकता है, आपको इसे हर जगह फिर से लिखना नहीं है।

+0

कॉपी कन्स्ट्रक्टर कैसा दिखता है? क्या आप मुझे कुछ पॉइंटर्स दे सकते हैं? – Nick

+0

सी # में "प्रतिलिपि बनाने वाले" नहीं हैं। लेकिन आप निश्चित रूप से एक पुन: प्रयोज्य विधि लिख सकते हैं जो बेस क्लास स्वीकार करता है और व्युत्पन्न वर्ग का एक उदाहरण देता है, जिसमें सभी बेस क्लास सदस्यों की प्रतिलिपि बनाई जाती है। या आप सामान्य विचार के बारे में पूछ रहे थे? –

1

जैसा कि पहले के उत्तरों ने कहा है, आपको MyResults का एक नया उदाहरण तत्काल करने की आवश्यकता है, फिर गुणों को अपने परिणाम ऑब्जेक्ट से कॉपी करें। आपने पूछा कि "कॉपी कन्स्ट्रक्टर" क्या था - यह केवल एक कन्स्ट्रक्टर है जो ऑब्जेक्ट लेता है और ऑब्जेक्ट का निर्माण करने के लिए इसका उपयोग करता है।

MyResults myResults = new MyResults 
{ 
    SampleProperty1 = results.SampleProperty1, 
    SampleProperty2 = results.SampleProperty2 
}; 

अगर कोई गुण के बहुत सारे हैं और/या आप के लिए अनेक परिवर्तन कर रहे हैं:

public class Results 
    { 
     public string SampleProperty1 { get; set; } 
     public string SampleProperty2 { get; set; } 
    } 

    public class MyResults : Results 
    { 
     public MyResults(Results results) 
     { 
      SampleProperty1 = results.SampleProperty1; 
      SampleProperty2 = results.SampleProperty2; 
     } 
    } 

एक प्रति निर्माता आमतौर पर, अधिक सुविधाजनक पठनीय और इस तरह कोड का उपयोग करने से पुन: प्रयोज्य है: उदाहरण के लिए कक्षा आप गुणों की प्रतिलिपि बनाने के लिए प्रतिबिंब (उदाहरण के लिए C# Using Reflection to copy base class properties) या ऑटोमैपर (http://automapper.codeplex.com) जैसे टूल का उपयोग कर सकते हैं। लेकिन अक्सर यह अधिक हो सकता है।

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