2010-01-07 4 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 вы можете позвонить только MemberwiseClone (или любым другим защищенным способом) по экземпляру X. (Или класс, производный от X)

Enemy Поскольку класс, который вы пытаетесь клон не наследует GameBase класса, который вы пытаетесь клонировать его, вы получаете эту ошибку.

Чтобы это исправить, добавить Clone публичный метод для Enemy, как это:

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

Но я думал, что MemberwiseClone был методом объекта, который Афайк из всех классов извращен? – Xenoprimate

+4

Да, но вы не можете вызвать защищенный метод другого класса, если он не наследует от _you_. В противном случае вы можете вызвать любого защищенного члена (в том числе «MemberwiseClone») в любом классе, просто наследуя его. Это сделало бы 'protected' почти бесполезным. – SLaks

+0

«защищенный» - это еще один способ сказать: только сам класс знает, когда MemberwiseClone() - это правильная вещь. Это редко, google «глубокая копия». –

25
  • вы не можете использовать MemberwiseClone() напрямую, вы должны реализовать его с помощью производного класса (рекомендуется)
  • но, с помощью отражения, вы можете обмануть его :)
  • вы можете использовать этот LITLE расширение для классов, которые не реализуют 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

+0

В Silverlight я получил 'System.MethodAccessException код пользователя: Message = Попытка методом 'ExtensionStaticClass.MemberwiseCloneEx (System .__ Canon)' для доступа к методу 'System.Object.MemberwiseClone()' failed' –

+0

В Silverlight нельзя использовать отражение для частных членов для обеспечения безопасности, ограниченное Microsoft, вы можете использовать сериализацию WCF для клонирования – 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); 
    } 
} 
Смежные вопросы