2010-01-07 81 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類,因此會出現此錯誤。

要解決此問題,增加公共Clone方法Enemy,像這樣:

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

的克隆,但我認爲MemberwiseClone是對象的方法,該方法afaik所有的課都是從哪裏來的? – Xenoprimate 2010-01-07 19:59:27

+4

是的,但不能調用其他類的受保護方法,除非它繼承自_you_。否則,只需從該類繼承,就可以調用任何受保護的成員(包括'MemberwiseClone')。這會使得「受保護」幾乎無用。 – SLaks 2010-01-07 20:00:36

+0

「保護」是另一種說法:只有類本身知道什麼時候MemberwiseClone()是正確的。它很少是谷歌「深度複製」。 – 2010-01-07 20:24:16

25
  • 您不容使用MemberwiseClone()直接,你必須通過派生類中實現它(recomended)
  • 但是,通過反射,你可以欺騙它:)
  • 你可以使用類這個痘痘的擴展,沒有實現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

我不明白爲什麼MemberwiseClone不公開......而上面的「作弊」是非常有用的!豎起大拇指! – Shaamaan 2012-10-17 08:39:27

+0

在Silverlight中,System.MethodAccessException未被用戶代碼處理:Message =嘗試通過方法'ExtensionStaticClass.MemberwiseCloneEx (System .__ Canon)'來訪問方法'System.Object.MemberwiseClone()'failed' – 2012-11-23 01:33:44

+0

在Silverlight中不能使用反射到私有成員的安全性,受限於微軟,你可以使用WCF序列化克隆 – ModMa 2013-09-24 21:44:39

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); 
    } 
}