2010-01-07 89 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); 
    } 
}