2010-01-07 16 views
13

मैं मेरा एक कस्टम वर्ग पर .MemberwiseClone() उपयोग करने के लिए कोशिश कर रहा हूँ पर नहीं पहुँच सकता है, लेकिन यह यह त्रुटि फेंकता है:संरक्षित सदस्य 'object.MemberwiseClone()'

Cannot access protected member 'object.MemberwiseClone()' via a qualifier of type 'BLBGameBase_V2.Enemy'; the qualifier must be of type 'BLBGameBase_V2.GameBase' (or derived from it) 

इसका क्या मतलब है? या बेहतर अभी तक, मैं Enemy कक्षा को कैसे क्लोन कर सकता हूं?

उत्तर

28

किसी भी कक्षा X के भीतर, आप X के उदाहरण पर केवल MemberwiseClone (या कोई अन्य संरक्षित विधि) पर कॉल कर सकते हैं। (या एक वर्ग X से प्राप्त)

Enemy वर्ग है कि आप क्लोन की कोशिश कर रहे GameBase वर्ग है कि आप इसे में क्लोन करने के लिए कोशिश कर रहे हैं के वारिस नहीं है के बाद से, आपको यह त्रुटि हो रही है।

इसे ठीक करने के Enemy के लिए एक सार्वजनिक Clone विधि जोड़ने के लिए, इस तरह:

class Enemy : ICloneable { 
    //... 
    public Enemy Clone() { return (Enemy)this.MemberwiseClone(); } 
    object ICloneable.Clone() { return Clone(); } 
} 
+1

की क्लोनिंग की अनुमति देता है लेकिन मैंने सोचा था MemberwiseClone वस्तु की एक विधि, था जो afaik सभी वर्गों से घिरे हुए हैं? – Xenoprimate

+4

हां, लेकिन आप एक अलग वर्ग की संरक्षित विधि को कॉल नहीं कर सकते हैं जब तक कि यह _you_ से प्राप्त न हो। अन्यथा, आप उस वर्ग से विरासत में किसी भी वर्ग पर किसी भी संरक्षित सदस्य ('MemberwiseClone' सहित) को कॉल करने में सक्षम होंगे। इससे 'सुरक्षित' लगभग बेकार हो जाएगा। – SLaks

+0

"संरक्षित" कहने का एक और तरीका है: केवल कक्षा ही जानता है जब सदस्यwiseक्लोन() करना उचित बात है। यह शायद ही कभी है, गूगल "गहरी प्रति"। –

25
  • आप MemberwiseClone (का उपयोग नहीं कर सकते) सीधे, आप इसे व्युत्पन्न वर्ग के माध्यम से लागू करना चाहिए (सिफारिश)
  • लेकिन, प्रतिबिंब के माध्यम से, आप इसे धोखा कर सकते हैं :)
  • आप कक्षाओं के लिए इस से थोड़ा विस्तार है जो ICloneable को लागू नहीं कर उपयोग कर सकते हैं:

    /// <summary> 
    /// Clones a object via shallow copy 
    /// </summary> 
    /// <typeparam name="T">Object Type to Clone</typeparam> 
    /// <param name="obj">Object to Clone</param> 
    /// <returns>New Object reference</returns> 
    public static T CloneObject<T>(this T obj) where T : class 
    { 
        if (obj == null) return null; 
        System.Reflection.MethodInfo inst = obj.GetType().GetMethod("MemberwiseClone", 
         System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); 
        if (inst != null) 
         return (T)inst.Invoke(obj, null); 
        else 
         return null; 
    } 
    
+3

मुझे समझ में नहीं आ रहा है कि क्यों सदस्यवाईक्लोन सार्वजनिक नहीं है ... और उपर्युक्त "धोखा" बहुत उपयोगी है! थम्स अप! – Shaamaan

+0

सिल्वरलाइट में, मुझे 'System.MethodAccessException को उपयोगकर्ता कोड द्वारा अनचाहे किया गया था: संदेश = विधि द्वारा प्रयास' ExtensionStaticClass.MemberwiseCloneEx (सिस्टम .__ कैनन) 'विधि का उपयोग करने के लिए' System.Object.MemberwiseClone() 'विफल' –

+0

सिल्वरलाइट में सुरक्षा के लिए निजी सदस्यों को प्रतिबिंब का उपयोग नहीं किया जा सकता है, माइक्रोसॉफ्ट द्वारा सीमित, आप क्लोन – ModMa

0

यहाँ एक विस्तार विधि है कि किसी भी वस्तु (चेतावनी के साथ उपयोग है कि यह सभी मामलों में काम नहीं)

public static class Extra_Objects_ExtensionMethods 
{ 
    public static T clone<T>(this T objectToClone) 
    { 
     try 
     { 
      if (objectToClone.isNull()) 
       "[object<T>.clone] provided object was null (type = {0})".error(typeof(T)); 
      else 
       return (T)objectToClone.invoke("MemberwiseClone"); 
     } 
     catch(Exception ex) 
     { 
      "[object<T>.clone]Faild to clone object {0} of type {1}".error(objectToClone.str(), typeof(T)); 
     } 
     return default(T); 
    } 
} 
संबंधित मुद्दे