11

I'm confused about how to use the MemberwiseClone() method. I looked the example in MSDN and they use it trough the this keyword.

Why I can not call it directly as other objects' methods like GetType() or ToString()? Another related method that does not appear is ShallowCopy().

If they are part of the Object class why can't I see them?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
mjsr
  • 7,410
  • 18
  • 57
  • 83

2 Answers2

14

The MemberwiseClone() function is protected, so you can only access it through a qualifier of your own type.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    damn i still don't get it. For example look the DerivedPoint example in http://msdn.microsoft.com/es-es/library/bcd5672a(VS.80).aspx , the derived class access directly the protected inherited members, with the MemberwiseClone i can't do that – mjsr May 19 '11 at 23:52
  • 1
    @voodoomsr: By "I don't get it" are you saying that you don't understand what "protected" means, or that you don't understand why the method is protected? – Eric Lippert May 19 '11 at 23:59
  • @Eric look the example in the url that i put. In the DerivedPoint instance they access inherited protected members directly. I don't get it why that is fine and what i try to do not. – mjsr May 20 '11 at 00:18
  • @voo: You can do that with `MemberwiseClone`, **as long as the qualifier is of your type**. – SLaks May 20 '11 at 00:31
  • @Slacks, can you give me an example please?, i don't understand the bold phrase :( – mjsr May 20 '11 at 02:06
  • @voo: The _qualifier_ is the object you call the method on (eg, `this`). Its compile-time type must be the class your method is in. – SLaks May 20 '11 at 03:16
  • Works: `new MyClass().MemberwiseClone()`. Doesn't work: `new UnrelatedClass().MemberwiseClone()`. – SLaks May 20 '11 at 03:17
  • 1
    @Voodoomsr: SLaks is right. The reason is that "protected" means "only accessible within this type or a subtype of this type". Suppose you have a protected method on object. Suppose a subtype of object, Animal, overrides that protected method. Now suppose another subtype of object, Tricycle, tries to access the method on Animal. That's not legal; even though Tricycle is a subtype of object, Tricycle is *not a subtype of Animal*. – Eric Lippert May 20 '11 at 04:45
  • let me see if i understand. The object that access the method is the object that contains the call(the complete sentence), not the object using to retrieve the method definition, i.e. MyClass().MemberwiseClone() is going to work only if as a sentence is contained in the same MyClass or in a subtype of it. I think that the reason of my misunderstanding is that i tought that MyClass().PrivateMembercall() would work always because MyClass is efectivelly the same class, ignoring where the sentence really occurs. I'm ok now? – mjsr May 20 '11 at 12:41
  • 4
    @voodoomsr: The rules for protected access are a bit complicated, yes. Summing up. Suppose base class B has a protected method M. B has derived classes, D and E. A call made from inside D is of the form r.M(). The compile-time type of r is required to be D or a type derived from D. r's type may not be E, because E.M is not accessible from D; D does not get to call E's protected member. r's type may not be B, because then r *might* be an E at runtime. – Eric Lippert May 20 '11 at 22:31
  • @voodoomsr: These articles might help further: http://blogs.msdn.com/b/ericlippert/archive/tags/protected/ – Eric Lippert May 20 '11 at 22:32
  • @Eric, @Slacks thanks both, i think i finally get the idea, :D – mjsr May 21 '11 at 00:29
7

Here is an example, this is what I did and no problems so far.

public class ModelBase
{
    public T ShallowCopy<T>() where T : ModelBase
    {
        return (T)(MemberwiseClone());
    }
}

And call it like:

var cloned = User.ShallowCopy<User>();
Esteban
  • 3,108
  • 3
  • 32
  • 51
  • 4
    This method isn't really generic. This is a glorified cast. You could write this and it would compile: `var cloned = user.ShallowCopy();` but crash at execution time because a user is not a car. – Steven Liekens Apr 14 '19 at 15:15