32

I'm trying to use .MemberwiseClone() on a custom class of mine, but it throws up this error:

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)

What does this mean? Or better yet, how can I clone an Enemy class?

bluish
  • 26,356
  • 27
  • 122
  • 180
Xenoprimate
  • 7,691
  • 15
  • 58
  • 95

3 Answers3

47

Within any class X, you can only call MemberwiseClone (or any other protected method) on an instance of X. (Or a class derived from X)

Since the Enemy class that you're trying to clone doesn't inherit the GameBase class that you're trying to clone it in, you're getting this error.

To fix this, add a public Clone method to Enemy, like this:

class Enemy : ICloneable {
    //...
    public Enemy Clone() { return (Enemy)this.MemberwiseClone(); }
    object ICloneable.Clone() { return Clone(); }
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 3
    But I thought MemberwiseClone was a method of Object, which afaik all classes are dervied from? – Xenoprimate Jan 07 '10 at 19:59
  • 5
    Yes, but you can't call a different class's protected method unless it inherits from _you_. Otherwise, you'd be able to call any protected member (including `MemberwiseClone`) on any class simply by inheriting from that class. This would make `protected` almost useless. – SLaks Jan 07 '10 at 20:00
  • "protected" is another way of saying: only the class itself knows when MemberwiseClone() is the proper thing to do. It rarely is, google "deep copy". – Hans Passant Jan 07 '10 at 20:24
  • `ICloneable` not available in Silverlight 5.0 – Peter Lee Nov 23 '12 at 01:34
  • @PeterLee: You don't need to use `ICloneable`. – SLaks Nov 23 '12 at 03:23
  • @SLaks, I see. but it seems we have to create a new class to inherit a built-in class. What I really need is to make a clone of an instance of an existing class, such `UIElement`, see my question: http://stackoverflow.com/questions/13522001/silverlight-how-to-make-a-shallowcopy-of-a-uielement – Peter Lee Nov 23 '12 at 05:02
  • What is that second line for?? – pete Jun 07 '23 at 08:12
38
  • you can´t use MemberwiseClone() directly, you must implement it via derived class (recomended)
  • but, via reflection, you can cheat it :)
  • you can use this litle extension for the classes that not implement 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;
    }
    
ModMa
  • 509
  • 4
  • 5
  • 7
    I cannot understand why MemberwiseClone isn't public... And the above "cheat" is very useful! Thumbs up! – MBender Oct 17 '12 at 08:39
  • In Silverlight, I got `System.MethodAccessException was unhandled by user code: Message=Attempt by method 'ExtensionStaticClass.MemberwiseCloneEx(System.__Canon)' to access method 'System.Object.MemberwiseClone()' failed` – Peter Lee Nov 23 '12 at 01:33
  • In Silverlight can't use reflection to private members for security, limited by microsoft, you can use WCF serialization for clone – ModMa Sep 24 '13 at 21:44
  • 2
    @Shaamaan: it's not public because it's up to the class-owner to determine how cloning should work; it's not necessarily safe for an arbitrary class to be cloned bit-for-bit. What would a bitwise clone of a `Thread` instance mean, for example? – Asherah Feb 19 '14 at 04:22
  • this cheat works nicely, BUT beware of the performance impact due to usage of Reflection. I would'nt recommend using this function, if you have thousands (or even more) of clone operations to be done – radomeit Jul 29 '20 at 12:49
-1

here is an extension method that allows the cloning of any object (use with the caveat that it not work in all cases)

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);
    }   
}
Dinis Cruz
  • 4,161
  • 2
  • 31
  • 49