2010-02-18 11 views
28

मैं नीचे इस कोड के साथ उलझन में हूँ, डेवलपर वर्ग सिर्फ एक कर्मचारी क्लोन बनाने कीविधिwiseClone() विधि क्या है?

Developer devCopy = (Developer)dev.Clone(); 

क्लोन विधि है, तो कैसे डेवलपर डेवलपर का एक और क्लोन मिलता है।

public abstract class Employee 
{ 
    public abstract Employee Clone(); 

    public string Name { get; set; } 
    public string Role { get; set; } 
} 


public class Typist : Employee 
{ 
    public int WordsPerMinute { get; set; } 

    public override Employee Clone() 
    { 
     return (Employee)MemberwiseClone(); 
    } 

    public override string ToString() 
    { 
     return string.Format("{0} - {1} - {2}wpm", Name, Role, WordsPerMinute); 
    } 
} 


public class Developer : Employee 
{ 
    public string PreferredLanguage { get; set; } 

    public override Employee Clone() 
    { 
     return (Employee)MemberwiseClone(); 
    } 

    public override string ToString() 
    { 
     return string.Format("{0} - {1} - {2}", Name, Role, PreferredLanguage); 
    } 
} 


Developer dev = new Developer(); 
dev.Name = "Bob"; 
dev.Role = "Team Leader"; 
dev.PreferredLanguage = "C#"; 

Developer devCopy = (Developer)dev.Clone(); 
devCopy.Name = "Sue"; 

Console.WriteLine(dev); 
Console.WriteLine(devCopy); 

/* OUTPUT 

Bob - Team Leader - C# 
Sue - Team Leader - C# 

*/ 

Typist typist = new Typist(); 
typist.Name = "Kay"; 
typist.Role = "Typist"; 
typist.WordsPerMinute = 120; 

Typist typistCopy = (Typist)typist.Clone(); 
typistCopy.Name = "Tim"; 
typistCopy.WordsPerMinute = 115; 

Console.WriteLine(typist); 
Console.WriteLine(typistCopy); 

/* OUTPUT 

Kay - Typist - 120wpm 
Tim - Typist - 115wpm 

*/ 

उत्तर

45

क्योंकि विधि MemberwiseClone() आपके लिए यह कर रही है। the documentation

देखें MemberwiseClone विधि एक नई वस्तु बनाने, और फिर नई वस्तु के लिए वर्तमान वस्तु के nonstatic क्षेत्रों को कॉपी करके एक उथले कॉपी बन जाती है। यदि कोई फ़ील्ड मान प्रकार है, तो फ़ील्ड की बिट-बाय-बिट प्रतिलिपि की जाती है। यदि कोई फ़ील्ड संदर्भ प्रकार है, तो संदर्भ कॉपी किया गया है लेकिन निर्दिष्ट वस्तु नहीं है; इसलिए, मूल वस्तु और उसका क्लोन एक ही वस्तु का संदर्भ देता है।

जब भी आप एक विधि आप नहीं unerstand कर देखते हैं, आप पता लगा सकते हैं, जो इसे घोषित किया है (दृश्य स्टूडियो में, मुझे लगता है), और बदले में अपने दस्तावेज़ देखें। इससे ज्यादातर चीजें काफी स्पष्ट होती हैं।

+0

आमतौर पर आपको क्लोन करने की आवश्यकता होती है। आदिम फ़ील्ड अलग-अलग प्रतियां हैं - निश्चित रूप से क्लोन। MemberwiseClone का एक आदिम फ़ील्ड बदलना स्रोत ऑब्जेक्ट में नहीं देखा जाएगा। ऑब्जेक्ट संदर्भ फ़ील्ड समान हैं। किसी अन्य वस्तु को इंगित करने से दूसरे को प्रभावित नहीं होगा। हालांकि, MemberwiseCloning ऑब्जेक्ट संदर्भों के बाद सीधे एक ही ऑब्जेक्ट को इंगित करता है। क्लोनिंग केवल प्रत्यक्ष वस्तु स्तर पर होती है, यह एक पुनरावर्ती प्रक्रिया नहीं है। मेरे अनुभव में, यह आम बात नहीं है कि आपको एक रिकर्सिव गहरे क्लोन की आवश्यकता है, इसलिए मैं आमतौर पर डीप क्लोन फ़ंक्शन बनाने में परेशान नहीं होता हूं। – Todd

11

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

यदि आप विरासत कक्षा में क्लोनिंग की अनुमति देना चाहते हैं, तो आपको protected virtual T BaseClone<T>() क्लोनिंग विधि परिभाषित करनी चाहिए; बेस-स्तरीय वर्ग जो Object से निकलती है उसे base.MemberwiseClone पर कॉल करना चाहिए; नए उदाहरण प्राप्त करने के लिए अन्य सभी वर्गों को base.BaseClone<T> का उपयोग करना चाहिए और फिर किसी ऑब्जेक्टिव क्लोनेबल फ़ील्ड को मूल ऑब्जेक्ट में क्लोन के साथ प्रतिस्थापित करना चाहिए।

मैं भी निम्नलिखित इंटरफेस को परिभाषित करने की सिफारिश करेंगे:

interface ISelf<out T> {T Self();} 
interface ICloneable<out T> : ISelf<T> {T Clone();} 

कि परिस्थितियाँ होती हैं जिनमें एक वर्ग कुछ वंशज जो क्लोन किया जा सकता है और कुछ नहीं कर सकते हैं जो हो सकता है के लिए अनुमति देगा। जिन्हें क्लोन किया जा सकता है, वे सार्वजनिक क्लोनिंग विधियों का पर्दाफाश कर सकते हैं (जो श्रृंखला को BaseClone<theirOwnType> पर ले जाना चाहिए)। जिन तरीकों को आधार प्रकार के क्लोनेबल डेरिवेटिव की आवश्यकता होती है वे ICloneable<theBaseType> के पैरामीटर का उपयोग कर सकते हैं; इससे उन्हें आधार प्रकार के किसी भी क्लोनेबल व्युत्पन्न को स्वीकार करने की अनुमति मिल जाएगी, भले ही ऐसे सभी डेरिवेटिव एक सामान्य आधार वर्ग साझा न करें।

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