Copy constructors and clones

D

Daniel O'Connell

From what I've read I'd argue that copy constructors are not better,
What that you have read about them that leads you to believe this ? Please
give technical arguments.


Come again ? A copy constructor always defines the type which is to be
copied at compile time as part of the signature of the constructor. I have
no idea to what the term "Composition arguments" refers.
That is entirely the problem. It defines the type at compile time, meaning
you are restricted(and damned) to loosing data when you create the copy.
Imagine a case where you recieve MyObject as a parameter, something like:

public MyObject DoSomeStuffToMyObjectWithCopy(MyObject obj)
{
MyObject newObj = new MyObject(obj);
//do something
return newObj.
}

called as:
MyDerivedObject derivedObj;
MyDerivedObject (MyDerivedObject)DoSomeStuffToMyObjectWithCopy(derivedObj);
//cast exception

consider the same case with a clone:
public MyObject DoSomeStuffToMyObjectWithCopy(MyObject obj)
{
MyObject newObj = MyObject.Clone();
//do something
return newObj.
}

called as:
MyDerivedObject derivedObj;
MyDerivedObject (MyDerivedObject)DoSomeStuffToMyObjectWithCopy(derivedObj);
//shouldn't be an issue here.
I wouldn't ever consider an object of type MyObject to be a clone or copy of
an object of type MyDerivedObject. This is much more of a conversion in my
mind rather than a copy, even if its to a similar type.

As for composition, that was in reference to Jay B. Harlows comments about
things like System.IO where Stream and the various readers often rely on
other readers derived from the same class, in essence by using composition.
Without documentation programmers are going to suffer no matter what your
methods are called. Why would anyone want to create a badly typed
constructor, and how would this differ from a badly implemented Clone()
method ? As far as "complicated language rules that not everyone is familiar
with", programming is not a popularity contest nor are copy constructors any
more complicated than any other language construct.
Obviously its not a popularity contest, but intentionally employeeing a
feature that increases the chances of programmer mistake is irresponsible in
my mind. For example, do you know the rules for how VB or C#, for example,
resolves every possible overload scenario, or if there are differences
between them? I've run into a few surprises myself, I wouldn't be very
pleased if a language quirk takes away the ability to perform a copy. Copy
constructors themselves aren't particularly complicated, but when combined
with overload resolution rules and a large number of languages you have to
take into consideration, I would call the issue complicated at the least.
If your opposition to copy constructors are that they are not aesthetically
pleasing to you, it is probably because you haven't used them very much. I
assume that is what you mean by "grace" in this context.


"Using a copy constructor tells me I have a copy of an object, while calling
Clone() leaves me wondering if I'll get a copy or a aggregate object, or
simply an object that takes a limited set of settings from another
object(perhaps preferences without data)."
Properly implemented, MyObject.Clone certainly says to me that its going to
be cloning, while new MyObject(myObjectReference) just says that you are
creating a new object. There is a level of obviousness that copy
constructors don't have.
What is relevant data is determined by the designer of the classes in the
hierarchy in which the copy constructor resides. Why is Clone() any better ?
What guarantee do I have that all relevant data has been copied from the
current object and its base classes into the object I have cloned ? It is
once again a decision of the designer of the class.
You don't have a guarentee, of course in programming you'll never have a
guarentee. However Clone gives you a reasonable expectation and a
polymorphic way to ensure all data is copied. Copying only the fields in the
base class is irresponsible, IMHO, and by relying on the base class
developer to provide copying you are doing just that, when you use Clone you
are relying on the implementer in the actual class, not the concrete type
you chose. I would say that implementer has a better shot at getting all of
the right fields copied, wouldn't you?

Interfaces are member function contracts and do not contain data AFAIK.


See above.
Hrmm, have you ever done any loosely coupled programming? Or tried to do a
plugin system? You *NEVER* know concrete types ahead of time, only
interfaces. When you want to issue a clone call to an object that you know
only by a set of interfaces, explicit copy constructors are unable to
achieve that.

IMyDataSource src;

//I want to copy src...can't be done without Clone(or reflection, which
seems silly).
It certainly is easier to call the base class's constructor to initialize
base class data from a copy, and initialize just the data in your own class
from a copy, than having to initialize all data in all base classes
including your own class from a copy. I believe you have to be kidding to
feel otherwise. As I also previously pointed out, there is no way to
initialize private base class data in my derived class when doing Clone()
since I have no access to it. But that is not a problem using copy
constructors since each class in hierarchy initializes its own data from
the copy used to construct the original object.
Yes, however, I don't feel you have to use a constructor in *most* cases.
Whats the serious difference in writing a constructor:
//in MyObject
MyObject(MyObject o)
{
this.MyBaseField=o.MyBaseField;
}

//in MyDerivedObject
MyDerivedObject(MyDerivedObject o) : this(o)
{
this.MyDerivedFIeld = o.MyDerivedField);
}

and
//in MyObject
public virtual object Clone()
{
return Clone(new MyObject());
}
protected virtual Clone(MyObject o)
{
o.MyBaseField = this.MyBaseField;
}
//in MyDerivedObject
public override object Clone()
{
return Clone(new MyDerivedObject());
}
protected virtual Clone(MyObject o)
{
MyDerivedObject = o as MyDerivedObject; //not needing this line isn't
sufficent, I'm afraid
d.MyDerivedField = this.MyDerivedField
base.Clone(o)
}
I have no issue with protected copy constructors. Another poster gave me a
very good method of implementing Clone() using protected copy constructors.
That just shows me that the copy constructor technique is not flawed. That
technique is certainly a workable implementation for Clone() and the only
way to copy private data from the base class.
It shows its not flawed when used in a protected manner, but I'd call it a
flawed model for public copying. However as I showed above its not the only
way to achieve a copy. Constructors are only nessecery in the case of read
only fields...which I personally consider to be irresponsible at the
instance level in general.
Again that is an aesthetic call. If you have programmed in a language where
copy constructors create an easy to program methodology of creating an
object based on another object of the same type, than copy constructors are
more natural than Clone().
More of an issue of reality. In most of languages in the .NET framework,
copy constructors are not normal. It is aesthetics, granted, but I disagree
that it is proper to adopt something that the smaller set of the major
languages uses simply because some people feel its easier.
I have explained why it is better a number of times in this thread. However
the technique of creating Clone() using a protected copy constructor is fine
with me, and does have the added attraction that once I implement it, other
objects know I am cloneable. I don't believe your own arguments have
technical merit but rely on aesthetics and "unknown" sources. Please argue
the technical issues youirself and not bring up language prejudices. I am
not supporting copy constructors because it is C++ but because it is an easy
and safe method to create an object based on another object. If it can be
abused, it is no different from an implementer of Clone() abusing that
functionality. Finally, as I have repeatedly shown, unless Clone() is
implemented using copy constructors, it is broken if base classes have
private data that need to be cloned also.
Please, before attacking me about technical merit, provide some. All your
arguments boil down to "Its easier in languages where you are used to it",
which I find to be far more aesthetic than technical...perhaps you disagree?
 
E

Edward Diener

Daniel said:
That is entirely the problem. It defines the type at compile time,
meaning you are restricted(and damned) to loosing data when you
create the copy. Imagine a case where you recieve MyObject as a
parameter, something like:

public MyObject DoSomeStuffToMyObjectWithCopy(MyObject obj)
{
MyObject newObj = new MyObject(obj);
//do something
return newObj.
}

called as:
MyDerivedObject derivedObj;
MyDerivedObject
(MyDerivedObject)DoSomeStuffToMyObjectWithCopy(derivedObj); //cast
exception

consider the same case with a clone:
public MyObject DoSomeStuffToMyObjectWithCopy(MyObject obj)
{
MyObject newObj = MyObject.Clone();
//do something
return newObj.
}

called as:
MyDerivedObject derivedObj;
MyDerivedObject
(MyDerivedObject)DoSomeStuffToMyObjectWithCopy(derivedObj);
//shouldn't be an issue here.
I wouldn't ever consider an object of type MyObject to be a clone or
copy of an object of type MyDerivedObject. This is much more of a
conversion in my mind rather than a copy, even if its to a similar
type.

I agree. This is certainly a case for Clone() doing the right thing since it
is polymorphic. You have made me realize that Clone() works when the actual
object type is not known, something I realized before but have forgotten. I
have needed this type of cloning of a reference object a few times in the
past and invented my own clone function, so I am glad .NET does have it and
I now realize why. Still implementing Clone() with an object in any other
way than using copy constructors internally is certainly not something I
would ever want to do.
As for composition, that was in reference to Jay B. Harlows comments
about things like System.IO where Stream and the various readers
often rely on other readers derived from the same class, in essence
by using composition.

Yes, Mr. Harlow was the one who pointed out to me that Clone() should be
done internally by using protected copy constructors. I don't see how his
remarks on composition can be a problem for copy constructors. One must copy
all relevant data in the copy constructor, including instantiated other
objects which make up the composition of a class. If there is no way to copy
an instantiated object within a class, then one must give up on copy
construction and cloning. Not every class can be reliably copied or cloned.
Obviously its not a popularity contest, but intentionally employeeing
a feature that increases the chances of programmer mistake is
irresponsible in my mind.

Who is to decide what increases the chances of a programmer's mistake ? I
don't worry about other programmer's mistakes. I worry instead about the
ease and clarity of my own ideas and implementations.
For example, do you know the rules for how
VB or C#, for example, resolves every possible overload scenario, or
if there are differences between them? I've run into a few surprises
myself, I wouldn't be very pleased if a language quirk takes away the
ability to perform a copy. Copy constructors themselves aren't
particularly complicated, but when combined with overload resolution
rules and a large number of languages you have to take into
consideration, I would call the issue complicated at the least.

I do not think it is complicated at all in any language. It has a specific
meaning and no class needs to implement it, but just support the notion
under .NET. I am not mandating copy constructors as something that must be
done, only suggesting for it to be something that can be done across
languages.
Properly implemented, MyObject.Clone certainly says to me that its
going to be cloning, while new MyObject(myObjectReference) just says
that you are creating a new object. There is a level of obviousness
that copy constructors don't have.

I agree that they are two different things, and you have made me realize
their difference. But I don't see that the meaning of cloning is any less or
more obvious than the meaning of creating an object by copying. Cloning is
polymorphic, since it is a virtual member function, while copy construction
is static since it is a construction. Internally cloning has to use copy
construction to work properly. Whether that copy construction is surfaced as
a public constructor, my own preference, or is just a protected constructor
for the purpose of cloning, is not a big issue with me. But to claim it
shouldn't exist as a recognized technique for making a copy of an object is
something with which I do not agree.
You don't have a guarentee, of course in programming you'll never
have a guarentee. However Clone gives you a reasonable expectation
and a polymorphic way to ensure all data is copied. Copying only the
fields in the base class is irresponsible, IMHO, and by relying on
the base class developer to provide copying you are doing just that,
when you use Clone you are relying on the implementer in the actual
class, not the concrete type you chose. I would say that implementer
has a better shot at getting all of the right fields copied, wouldn't
you?

No, because the implementer can't access all the data in the base class to
make a copy of it. Please answer my original objection to cloning without
copy construction as I defined it: How does the cloner access base class
private data ?

Also think about the extra work which must be done even if there is no
private data in any of the base classes, an unlikely situation. The cloner
must make copies of all variables in the hierarchy of classes beneath him.
Ugh ! Whereas with copy construction I need only make copies of my own
class's data and let the base classes make copies of their own data. Can you
really believe that your method is better ? Please think about it since I
can not believe that you don't see how much clearer and safe copy
construction is as a technique than your method of cloning.
Hrmm, have you ever done any loosely coupled programming?

All the time.
Or tried to
do a plugin system? You *NEVER* know concrete types ahead of time,
only interfaces.

This has little to so with anything.
When you want to issue a clone call to an object
that you know only by a set of interfaces, explicit copy constructors
are unable to achieve that.

Sorry, you are voicing opinions instead of issuing technical arguments.
Please explain how interfaces negatively affect copy construction and
positively affect cloning, especially as there is no data in them to copy or
clone.
IMyDataSource src;

//I want to copy src...can't be done without Clone(or reflection,
which seems silly).

This last is meaningless and I can't even begin to decipher what you mean.
Yes, however, I don't feel you have to use a constructor in *most*
cases. Whats the serious difference in writing a constructor:
//in MyObject
MyObject(MyObject o)
{
this.MyBaseField=o.MyBaseField;
}

//in MyDerivedObject
MyDerivedObject(MyDerivedObject o) : this(o)
{
this.MyDerivedFIeld = o.MyDerivedField);
}

OK, normal copy construction.
and
//in MyObject
public virtual object Clone()
{
return Clone(new MyObject());
}
protected virtual Clone(MyObject o)
{
o.MyBaseField = this.MyBaseField;
}

This last is the equivalent of a protected copy constructor, is it not ?
//in MyDerivedObject
public override object Clone()
{
return Clone(new MyDerivedObject());
}
protected virtual Clone(MyObject o)
{
MyDerivedObject = o as MyDerivedObject; //not needing this line
isn't sufficent, I'm afraid
d.MyDerivedField = this.MyDerivedField
base.Clone(o)
}

Again this last is equivalent of a protected copy constructor, is it not ?

What you have done is create protected copy constructors, but give them
names of MyOwnClass::Clone(myOwnobject) rather than
MyOwnClass::MyOwnClass(myOwnObject). At last we are completely agreed on the
efficacy of copy constructors. What a convoluted disussion we have had to
reach that agreement.

I would like to thank you for reminding me about the advantages of the
polymorphic nature of Clone(). I had indeed forgotten why it works so well
with polymorphic objects. I hope you will realize, given your last example,
why copy constructors are important, whether you want to call them copy
constructors or, as you have done in your last example, Clone(myOwnObject).
My main point regarding copy constructors is something which your example
shows you do understand: each base class in a class hierarchy needs to be
responsible for initializing and copying ( or cloning if you will ) its own
object.
 
D

Daniel O'Connell

Edward Diener said:
I agree. This is certainly a case for Clone() doing the right thing since it
is polymorphic. You have made me realize that Clone() works when the actual
object type is not known, something I realized before but have forgotten. I
have needed this type of cloning of a reference object a few times in the
past and invented my own clone function, so I am glad .NET does have it and
I now realize why. Still implementing Clone() with an object in any other
way than using copy constructors internally is certainly not something I
would ever want to do.


Yes, Mr. Harlow was the one who pointed out to me that Clone() should be
done internally by using protected copy constructors. I don't see how his
remarks on composition can be a problem for copy constructors. One must copy
all relevant data in the copy constructor, including instantiated other
objects which make up the composition of a class. If there is no way to copy
an instantiated object within a class, then one must give up on copy
construction and cloning. Not every class can be reliably copied or cloned.
The problem is naming collisions and resolution. In composition, a pattern
like public MyTextReader(TextReader reader); may exist.
MyTextReader(MyTextReader reader) may even exist, because the system is
designed to layer upon eachother in an aggregate manner. The problem is copy
constructors *could* collide with legitimate aggregate constructors and
cause a problem.
Who is to decide what increases the chances of a programmer's mistake ? I
don't worry about other programmer's mistakes. I worry instead about the
ease and clarity of my own ideas and implementations.


I do not think it is complicated at all in any language. It has a specific
meaning and no class needs to implement it, but just support the notion
under .NET. I am not mandating copy constructors as something that must be
done, only suggesting for it to be something that can be done across
languages.
The problem I am considering is, using similar code(same variable type and
numbeR) if VB, for example picks a copy constructor while C# picks a
different constructor that still matches types, but is not a copy
constructor, the results are different and confusing. This is of course
assuming the CLS doesn't define specifics on overload resolution(I dont know
offhand).
I agree that they are two different things, and you have made me realize
their difference. But I don't see that the meaning of cloning is any less or
more obvious than the meaning of creating an object by copying. Cloning is
polymorphic, since it is a virtual member function, while copy construction
is static since it is a construction. Internally cloning has to use copy
construction to work properly. Whether that copy construction is surfaced as
a public constructor, my own preference, or is just a protected constructor
for the purpose of cloning, is not a big issue with me. But to claim it
shouldn't exist as a recognized technique for making a copy of an object is
something with which I do not agree.
I wouldn't claim it shouldn't be a recognized technique *internally*, I just
don't feel it is proper to provide it to the end user, as it not a
particarly apparent pattern.
No, because the implementer can't access all the data in the base class to
make a copy of it. Please answer my original objection to cloning without
copy construction as I defined it: How does the cloner access base class
private data ?

Also think about the extra work which must be done even if there is no
private data in any of the base classes, an unlikely situation. The cloner
must make copies of all variables in the hierarchy of classes beneath him.
Ugh ! Whereas with copy construction I need only make copies of my own
class's data and let the base classes make copies of their own data. Can you
really believe that your method is better ? Please think about it since I
can not believe that you don't see how much clearer and safe copy
construction is as a technique than your method of cloning.


All the time.


This has little to so with anything.


Sorry, you are voicing opinions instead of issuing technical arguments.
Please explain how interfaces negatively affect copy construction and
positively affect cloning, especially as there is no data in them to copy or

This last is meaningless and I can't even begin to decipher what you mean.

What I mean is, consider you have an interface IMyInterface and a method
that recieves IMyInterface:

public void MyMethod(IMyInterface iface)
{
//if I want to create a copy of iface, .Clone is my only option, as I
don't know the concrete type of iface.
}

To be clear, my argument is not against using constructors to perform
copying, just against using those constructors anywehre outside of the
hiearchy they exist for, IE they should only be protected(or private if
viable). My primary disagreement is that they are misleading in name(they
don't really copy so much as convert when the object is a derivative of the
type the constructor resides in), not as easy to use or as obvious as
IClonable.Clone, how it is implemented internally is generally not an
issue(except in cases, as noted above, where overload collisions and
resolution gets hairy).
OK, normal copy construction.


This last is the equivalent of a protected copy constructor, is it not ?


Again this last is equivalent of a protected copy constructor, is it not ?

What you have done is create protected copy constructors, but give them
names of MyOwnClass::Clone(myOwnobject) rather than
MyOwnClass::MyOwnClass(myOwnObject). At last we are completely agreed on the
efficacy of copy constructors. What a convoluted disussion we have had to
reach that agreement.
It is similar to a copy constructor, however if you'll call any method that
performs a copy a "copy construtor", then the defintion of copy constructor
is broader than its name implies(you cannot copy an object without using
some method). As I said above, my personal feeling is that they are often
safer(and perhaps at times easier) implemented as a virtual method, if for
no reason than to maintain the chain. Constructors are not inherited(in most
languages anyway), and an implementation cannot be forced or even made
apparent by intellisense. Clone has a similar issue, you cannot skip a step
in clone with normal code, as the Clone() method only knows its own concrete
type(its feasible you could use a static factory method or require a
specific constructor and use reflection to create the object). This is
annoying, but not insurmountable, however a construct geared towards
requiring constructors and other higher level contractual constructs(such as
attributes, exceptions, etc) would have its value here as well.
I would like to thank you for reminding me about the advantages of the
polymorphic nature of Clone(). I had indeed forgotten why it works so well
with polymorphic objects. I hope you will realize, given your last example,
why copy constructors are important, whether you want to call them copy
constructors or, as you have done in your last example, Clone(myOwnObject).
My main point regarding copy constructors is something which your example
shows you do understand: each base class in a class hierarchy needs to be
responsible for initializing and copying ( or cloning if you will ) its own
object.
Yes, it obviously does, however my main issue is I don't feel those
constructors should be exposed, as I've mentioned above, which is the gist I
got from your posts. It is my opinion that the downsides of publically
exposed constructors is a detriment to the environment, and its not
something I would like to see spread around the FCL. However, I'll admit
that it is only an opinion and I am certainly not the only one that matters.
Sometimes religious language purity(and my beloved C#) cause me to do some
strange things, ;)
 
D

Daniel O'Connell

Interestingly, I just ran across an article[1] that addresses(although in
considerably less detail) this issue.
It also showed me a mistake I made, Clone does not have an issue with an
derivative skipping implementation of Clone, and this infact shows precisely
why copy constructors can't be used. For properly polymorphic code, the
Clone method should call MemberwiseClone, which creates a shallow copy of
your current object, with the proper type. This would then be modified with
deep copy calls via a protected method as I illustrated. This is the only
way a derivative object can elect to skip an implementation of Clone and
still allow the object to be cloned to the proper type. Any other situation
can cause two things: 1) a class along the derivation chain doesn't bother
to provide a copy constructor, breaking copy semantics and resulting in an
incorrectly(and probably incompletely) copied object or 2) a class along the
derivation chain doesn't override Clone and that object cannot clone itself,
calls to clone would result in a different type, although derived classes
should still clone correctly.

1. http://www.ondotnet.com/pub/a/dotnet/2002/11/25/copying.html
 
J

Jay B. Harlow [MVP - Outlook]

Daniel,
Interesting article & discussion.

I'll need to review it closer later to decide if I want to reevaluate the
Cloning method I used in my project.

I'll need to remember your comments about loosely coupled systems...

Thanks
Jay
 
E

Edward Diener

Daniel said:
The problem is naming collisions and resolution. In composition, a
pattern like public MyTextReader(TextReader reader); may exist.
MyTextReader(MyTextReader reader) may even exist, because the system
is designed to layer upon eachother in an aggregate manner. The
problem is copy constructors *could* collide with legitimate
aggregate constructors and cause a problem.

Only if the copy constructors use a name for something else which should be
copy constructors or a name for copy constructors which should be something
else. I do not design software worrying about what others have done. In
C++'s copy constructors, the name of the copy constructor always follows the
same pattern.
The problem I am considering is, using similar code(same variable
type and numbeR) if VB, for example picks a copy constructor while C#
picks a different constructor that still matches types, but is not a
copy constructor, the results are different and confusing. This is of
course assuming the CLS doesn't define specifics on overload
resolution(I dont know offhand).

Again you are pushing this point beyond reasonableness. If, if, if... . One
can only design based on standards to which all are agreed. In your own
example, if I call my protected Clone copy constructor Igloo instead, and
call my some other function which formats the hard drive Clone, and don't
tell you about it in decent documentation, is it your fault that your call
to the protected Clone copy constructor doesn't work said:
I wouldn't claim it shouldn't be a recognized technique *internally*,
I just don't feel it is proper to provide it to the end user, as it
not a particarly apparent pattern.

What is there to say ? You don't like it because you haven't used it in
class frameworks and therefore you don't feel it is "proper".
What I mean is, consider you have an interface IMyInterface and a
method that recieves IMyInterface:

public void MyMethod(IMyInterface iface)
{
//if I want to create a copy of iface, .Clone is my only option,
as I don't know the concrete type of iface.
}

Why am I copying interfaces when there is nothing to copy ? If there is
something to copy, interfaces can use protected copy constructors just like
anything else.
To be clear, my argument is not against using constructors to perform
copying, just against using those constructors anywehre outside of the
hiearchy they exist for, IE they should only be protected(or private
if viable). My primary disagreement is that they are misleading in
name(they don't really copy so much as convert when the object is a
derivative of the type the constructor resides in), not as easy to
use or as obvious as IClonable.Clone, how it is implemented
internally is generally not an issue(except in cases, as noted above,
where overload collisions and resolution gets hairy).

It is similar to a copy constructor, however if you'll call any
method that performs a copy a "copy construtor", then the defintion
of copy constructor is broader than its name implies(you cannot copy
an object without using some method). As I said above, my personal
feeling is that they are often safer(and perhaps at times easier)
implemented as a virtual method, if for no reason than to maintain
the chain. Constructors are not inherited(in most languages anyway),
and an implementation cannot be forced or even made apparent by
intellisense. Clone has a similar issue, you cannot skip a step in
clone with normal code, as the Clone() method only knows its own
concrete type(its feasible you could use a static factory method or
require a specific constructor and use reflection to create the
object). This is annoying, but not insurmountable, however a
construct geared towards requiring constructors and other higher
level contractual constructs(such as attributes, exceptions, etc)
would have its value here as well.

Yes, it obviously does, however my main issue is I don't feel those
constructors should be exposed, as I've mentioned above, which is the
gist I got from your posts. It is my opinion that the downsides of
publically exposed constructors is a detriment to the environment,
and its not something I would like to see spread around the FCL.
However, I'll admit that it is only an opinion and I am certainly not
the only one that matters. Sometimes religious language purity(and my
beloved C#) cause me to do some strange things, ;)

Your last paragraph is the only issue, a small one, in our disagreement. I
admit Clone works better because it is polymorphic whereas public copy
constructors are not polymorphic. Still underlying Clone must be a copy
constructor technique which calls down to each base class to make a copy of
its own object. This last is a tried and proven technique in OOP
programming. I don't mind Clone replacing public copy constructors in .NET
as it has the greater advantage of being polymorphic and allowing the
programmer, through interface, to see if an object is cloneable, ie. can
make a copy of itself. But without protected copy constructors, with
whatever name you want to call them, down through a hierarchy, Clone is
broken as far as I am concerned. Playing around with the concept and
claiming otherwise is just asking for headaches and problems, which I as a
programmer do not want to worry about.

I would rather have a regular name for my protected copy constructors, which
for me is the normal notation in C++ for copy constructors, than have to
guess at a name in each class. If you like the name Clone(myOwnObject)
better than the copy constructor notation, I don't object to that either, as
long as the .NET framework uses that also in its class hierarchy. But I
don't see the protected copy constructor technique for .NET classes and
therefore conclude that base-derived cloning in .NET is essentially broken,
or too onerous and difficult to worry about.

The rest of your arguments, about composition and different names and
interfaces, is just sophistry to me, ie. trying to win.
 
E

Edward Diener

Daniel said:
Interestingly, I just ran across an article[1] that
addresses(although in considerably less detail) this issue.
It also showed me a mistake I made, Clone does not have an issue with
an derivative skipping implementation of Clone, and this infact shows
precisely why copy constructors can't be used. For properly
polymorphic code, the Clone method should call MemberwiseClone, which
creates a shallow copy of your current object, with the proper type.
This would then be modified with deep copy calls via a protected
method as I illustrated.

Does MemberwiseClone do a deep copy of all base class objects ? I doubt it.
Then how do you propose to copy base class private variables which need deep
copies done ? Finally, in your own "deep copy of objects that need special
attention" you have to deep copy all protected variables from all base
classes manually. Once again, Ugh !!! And this flawed technique is better
than protected copy constructors ?

The method in the article is broken also, unless I have missed something
subtle about MemberwiseClone.

What have I missed here ?
This is the only way a derivative object can
elect to skip an implementation of Clone and still allow the object
to be cloned to the proper type. Any other situation can cause two
things: 1) a class along the derivation chain doesn't bother to
provide a copy constructor, breaking copy semantics and resulting in
an incorrectly(and probably incompletely) copied object or 2) a class
along the derivation chain doesn't override Clone and that object
cannot clone itself, calls to clone would result in a different type,
although derived classes should still clone correctly.

I agree with this in this sense. If a class in the derivation chain is not
cloneable, then my class is not cloneable. But I see nothing wrong with that
whereas you do.
 
J

Jon Skeet [C# MVP]

Edward Diener said:
Daniel said:
Interestingly, I just ran across an article[1] that
addresses(although in considerably less detail) this issue.
It also showed me a mistake I made, Clone does not have an issue with
an derivative skipping implementation of Clone, and this infact shows
precisely why copy constructors can't be used. For properly
polymorphic code, the Clone method should call MemberwiseClone, which
creates a shallow copy of your current object, with the proper type.
This would then be modified with deep copy calls via a protected
method as I illustrated.

Does MemberwiseClone do a deep copy of all base class objects ? I doubt it.

No, it does a shallow copy.
Then how do you propose to copy base class private variables which need deep
copies done ?

The top class in the hierarchy to provide a Clone method calls
MemberwiseClone and then adds any extra special touches (e.g. deep
copying of some variables). Any other classes in the hierarchy which
need deep copies of some variables override Clone and first call
base.Clone(), then modify the returned object appropriately before
returning it.
Finally, in your own "deep copy of objects that need special
attention" you have to deep copy all protected variables from all base
classes manually.

No - again, the base class should do this. Mind you, I don't think you
should have any protected variables in the first place...
Once again, Ugh !!! And this flawed technique is better
than protected copy constructors ?

Yes, unless you don't care about losing information.
 
E

Edward Diener

Jon said:
Edward Diener said:
Daniel said:
Interestingly, I just ran across an article[1] that
addresses(although in considerably less detail) this issue.
It also showed me a mistake I made, Clone does not have an issue
with an derivative skipping implementation of Clone, and this
infact shows precisely why copy constructors can't be used. For
properly polymorphic code, the Clone method should call
MemberwiseClone, which creates a shallow copy of your current
object, with the proper type. This would then be modified with deep
copy calls via a protected method as I illustrated.

Does MemberwiseClone do a deep copy of all base class objects ? I
doubt it.

No, it does a shallow copy.
Then how do you propose to copy base class private variables which
need deep copies done ?

The top class in the hierarchy to provide a Clone method calls
MemberwiseClone and then adds any extra special touches (e.g. deep
copying of some variables).

It still isn't getting the base class private variables copied.
Any other classes in the hierarchy which
need deep copies of some variables override Clone and first call
base.Clone(), then modify the returned object appropriately before
returning it.

1) The base.Clone() returns a Clone() of the base object. How do you propose
to use this to return the derived object ?
2) If the top class operates differently than the derived classes, what
happens when I derive an object from the top class ? I have to change the
top class methodology then for cloning ?

What you have written above doesn't make sense to me. Please explain.
No - again, the base class should do this.

Then how do I get them for my derived class's Clone.
Mind you, I don't think you
should have any protected variables in the first place...

That last sentence made me really laugh.
Yes, unless you don't care about losing information.

How does one lose information via copy constructors ?
 
J

Jon Skeet [C# MVP]

Edward Diener said:
It still isn't getting the base class private variables copied.

Yes it is, because that's what MemberwiseClone does.
1) The base.Clone() returns a Clone() of the base object. How do you propose
to use this to return the derived object ?

Cast it to the derived object - that's the thing, MemberwiseClone
returns an object of the *original* type. Don't forget, it's not like
there are two objects to start with, one derived and one base - there's
just the one derived object, which can also be used as a base object.
2) If the top class operates differently than the derived classes, what
happens when I derive an object from the top class ? I have to change the
top class methodology then for cloning ?

If the top class methodology doesn't do a deep copy and you want a deep
copy, you are indeed stuffed - as you would be with copy constructors.
Then how do I get them for my derived class's Clone.

Not sure what you mean here - MemberwiseClone will copy the private
variables for *all* the types in the hierarchy, both up and down from
where it is called.
That last sentence made me really laugh.

Why? It's fairly widely accepted practice these days, IME.

From Microsoft's .NET guidelines:

<quote>
Do not use instance fields that are public or protected
How does one lose information via copy constructors ?

Because they're not polymorphic, as we've discussed before. At least,
that is unless I've missed something. I was under the impression that
if I do:

Base b = new Derived();

and pass that to another method which only knows of it as Base but
which wants a copy, the other method is out of luck because it doesn't
know which type's constructor to use.

I think it's probably easiest to use an example here to show how
MemberwiseClone works:

using System;

public class Base : ICloneable
{
private int number;

public Base (int i)
{
number = i;
}

public virtual object Clone()
{
return MemberwiseClone();
}

public virtual void ShowStuff()
{
Console.WriteLine ("Base.ShowStuff: number={0}", number);
}
}

public class Derived : Base
{
private string name;

public Derived (string name, int i) : base (i)
{
this.name = name;
}

public override void ShowStuff()
{
base.ShowStuff();
Console.WriteLine ("Derived.ShowStuff: name={0}", name);
}
}

public class Test
{
static void Main()
{
Base b = new Derived("Hello", 5);
Base c = (Base) b.Clone();

c.ShowStuff();
}
}

The private members of both Base and Derived are copied in a shallow
fashion by MemberwiseClone. If you wanted a deep clone of something in
Derived, you'd override Derived.Clone:

public override object Clone()
{
Derived ret = (Derived) base.Clone();
ret.foo = DeepCopy(ret.foo); // Where foo is declared in derived
return ret;
}

Now, how would you accomplish all of the above (the private members of
both types being copied, optionally deeply, even when the code calling
Clone may not even know of the Derived type) using copy constructors?
 
D

Daniel O'Connell

Again you are pushing this point beyond reasonableness. If, if, if... . One
can only design based on standards to which all are agreed. In your own
example, if I call my protected Clone copy constructor Igloo instead, and
call my some other function which formats the hard drive Clone, and don't
tell you about it in decent documentation, is it your fault that your call
to the protected Clone copy constructor doesn't work <g> ?

So, you advocate doing things stupidly because, well, someone will read
about it and realize you did something stupid? Part of responsible
programming is writing reasonably and cleanly, in .NET that means
considering other major languages(which means every public and protected
interface I write needs to be highly compatible with VB, C++, and C#, and I
do spend time ensuring that it is), as well as providing a clean, CLS
compliant front. Not considering the ramifications of your design in
languages outside of your own is not good practice in this particular
system, you can't play by C++'s rules anymore, you have to play by .NET's.
What is there to say ? You don't like it because you haven't used it in
class frameworks and therefore you don't feel it is "proper".

Not sure how you get this, I just think that using
new MyObject(MyOldObjectReference); is not a clear or proper syntax. I don't
know why you feel you need to make personal attacks or defend this as if
your own honor was at stake, or why you need to denigrate(that is, to
belittle, I am perfectly capable of treating you like an idiot too) me
simply because I disagree. Your assertion that copy constructors are easier
when you use them is false, and utterly smacks of C++ arrogance.
Why am I copying interfaces when there is nothing to copy ? If there is
something to copy, interfaces can use protected copy constructors just like
anything else.
You don't seem to understand. How often do you deal with types you cannot
know the concrete type of? Using a copy constructor, a public one anyway, is
rank with problems, protected leaves you with the issues shown in my other
post(which I'll reply to soon enough)
Your last paragraph is the only issue, a small one, in our disagreement. I
admit Clone works better because it is polymorphic whereas public copy
constructors are not polymorphic. Still underlying Clone must be a copy
constructor technique which calls down to each base class to make a copy of
its own object. This last is a tried and proven technique in OOP
programming. I don't mind Clone replacing public copy constructors in .NET
as it has the greater advantage of being polymorphic and allowing the
programmer, through interface, to see if an object is cloneable, ie. can
make a copy of itself. But without protected copy constructors, with
whatever name you want to call them, down through a hierarchy, Clone is
broken as far as I am concerned. Playing around with the concept and
claiming otherwise is just asking for headaches and problems, which I as a
programmer do not want to worry about.
The problem I have here is you are not deliniating between the technique
used in copy constructors(which is, base class does its own work, which, in
retrospect, is used constantly in OO, isn't it? Why is this so special in
this case it gets its own name?), and copy constructors themselves. I don't
care about the technique, I find that using a constructor for the technique,
however, is bad practice and is going to cause you alot of grief in the long
run.
I would rather have a regular name for my protected copy constructors, which
for me is the normal notation in C++ for copy constructors, than have to
guess at a name in each class. If you like the name Clone(myOwnObject)
better than the copy constructor notation, I don't object to that either, as
long as the .NET framework uses that also in its class hierarchy. But I
don't see the protected copy constructor technique for .NET classes and
therefore conclude that base-derived cloning in .NET is essentially broken,
or too onerous and difficult to worry about.
Unless you are inheriting from that class, its irrelevent. What Clone()
calls is not of any concern to you. If you are, you are responsible for
figuring that out, considering a constructor doesn't even advertise its
existance, you will *HAVE* to go to the docs anyway, and with a constructor
you risk breaking things substanitally.
The rest of your arguments, about composition and different names and
interfaces, is just sophistry to me, ie. trying to win.
They are valid issues you seem to be refusing to listen to. To put it
simply, using a *constructor* to clone an object is a bad practice. With all
of your talk about not considering languages, you seem to be basing your
opinion entirely on C++, which frankly doesn't matter that much in the .NET
world.
I am not trying to win just to win, I am right, in the .NET world. Using
constructors to perform copies is irresponsible and a broken pattern, using
a method which performs the copy is *NOT* a constructor, its a method. I
don't care what C++ does, this is .NET.
 
D

Daniel O'Connell

Edward Diener said:
Daniel said:
Interestingly, I just ran across an article[1] that
addresses(although in considerably less detail) this issue.
It also showed me a mistake I made, Clone does not have an issue with
an derivative skipping implementation of Clone, and this infact shows
precisely why copy constructors can't be used. For properly
polymorphic code, the Clone method should call MemberwiseClone, which
creates a shallow copy of your current object, with the proper type.
This would then be modified with deep copy calls via a protected
method as I illustrated.

Does MemberwiseClone do a deep copy of all base class objects ? I doubt it.
Then how do you propose to copy base class private variables which need deep
copies done ? Finally, in your own "deep copy of objects that need special
attention" you have to deep copy all protected variables from all base
classes manually. Once again, Ugh !!! And this flawed technique is better
than protected copy constructors ?

The method in the article is broken also, unless I have missed something
subtle about MemberwiseClone.

What have I missed here ?

I think it still comes down to your, I must say odd, insistence that a
method that performs a copy is a copy constructor, and I am tired of arguing
this point, I've done it too many times.

And as Jon Skeet pointed out, you shouldn't be exposing variables as
protected anyway.
I agree with this in this sense. If a class in the derivation chain is not
cloneable, then my class is not cloneable. But I see nothing wrong with that
whereas you do.
Due to how MemberwiseClone works, a derivation that either doesn't add state
or that adds only generic state(that is primitives and strings), doesn't
need to handle any form of clone method. I find that *most* of my member
variables are of primitive type, and I've written more than one derivation
class that doesn't even create a class variable. Forcing a developer to
write a clone method when he has nothign to clone is just silly.
Implementing implies the object can be cloned, for proper operation you
should handle that, when nessecery, as I illustrated above, and object can
choose to not provide any clone code and stlll allow cloning.
 
E

Edward Diener

Jon said:
Why? It's fairly widely accepted practice these days, IME.

From Microsoft's .NET guidelines:

<quote>
Do not use instance fields that are public or protected
</quote>

Nonsense, as are all general dicta of this type ! Why not no
public/protected fields at all, just properties ? It is not a bad general
idea but there are always cases which provide exceptions, and I would rather
have freedom of implementation than straitjackets put upon me.
Because they're not polymorphic, as we've discussed before. At least,
that is unless I've missed something. I was under the impression that
if I do:

Base b = new Derived();

and pass that to another method which only knows of it as Base but
which wants a copy, the other method is out of luck because it doesn't
know which type's constructor to use.

That is true. That is why I said that using Clone() is fine, as long as one
uses protected copy constructors internally to do it. If one does not need
polymorphic cloning, something which I have found to be a rarity in actual
practice, just using copy constructors works fine.
I think it's probably easiest to use an example here to show how
MemberwiseClone works:

using System;

public class Base : ICloneable
{
private int number;

public Base (int i)
{
number = i;
}

public virtual object Clone()
{
return MemberwiseClone();
}

public virtual void ShowStuff()
{
Console.WriteLine ("Base.ShowStuff: number={0}", number);
}
}

public class Derived : Base
{
private string name;

public Derived (string name, int i) : base (i)
{
this.name = name;
}

public override void ShowStuff()
{
base.ShowStuff();
Console.WriteLine ("Derived.ShowStuff: name={0}", name);
}
}

public class Test
{
static void Main()
{
Base b = new Derived("Hello", 5);
Base c = (Base) b.Clone();

c.ShowStuff();
}
}

The private members of both Base and Derived are copied in a shallow
fashion by MemberwiseClone. If you wanted a deep clone of something in
Derived, you'd override Derived.Clone:

public override object Clone()
{
Derived ret = (Derived) base.Clone();
ret.foo = DeepCopy(ret.foo); // Where foo is declared in derived
return ret;
}

Now, how would you accomplish all of the above (the private members of
both types being copied, optionally deeply, even when the code calling
Clone may not even know of the Derived type) using copy constructors?

So essentially only the base class in a hierarchy calls MemberwiseClone,
doing any deep copies if necessary after it, and all other classes call
their base class clone and then do deep copies as appropriate. I believe
that is the explanation I missed in the article ?

That's fine but I find the following simpler and more regular.

using System;

public class Base : ICloneable
{
private int number;

public Base (int i)
{
number = i;
}

public virtual object Clone()
{
return (new Base(this));
}

protected Base ( Base c )
{
number = c.number;

// Copy any other base class objects including deep copy if necessary

}

public virtual void ShowStuff()
{
Console.WriteLine ("Base.ShowStuff: number={0}", number);
}
}

public class Derived : Base
{
private string name;

public Derived (string name, int i) : base (i)
{
this.name = name;
}

protected Derived(Derived d) : base(d)
{
// Copy any derived class objects, including deep copies if necessary
}

public virtual object Clone()
{
return (new Derived(this));
}

public override void ShowStuff()
{
base.ShowStuff();
Console.WriteLine ("Derived.ShowStuff: name={0}", name);
}
}

In my scheme, all classes use the same method of cloning. All Clone()
methods call their own protected copy constructors. All the protected copy
constructors are responsible for calling base class protected copy
constructors and copying their own data.

To me this is preferable to a base class doing MemberwiseClone and all other
classes calling the base class's Clone and then doing deep copies on
particular variables of the cloned object. I believe the call to
MemberwiseClone, which must involve reflection, is of greater overhead than
the simple protected copy constructor scheme I have advocated.

To each his own.
 
E

Edward Diener

Daniel said:
Edward Diener said:
Daniel said:
Interestingly, I just ran across an article[1] that
addresses(although in considerably less detail) this issue.
It also showed me a mistake I made, Clone does not have an issue
with an derivative skipping implementation of Clone, and this
infact shows precisely why copy constructors can't be used. For
properly polymorphic code, the Clone method should call
MemberwiseClone, which creates a shallow copy of your current
object, with the proper type. This would then be modified with deep
copy calls via a protected method as I illustrated.

Does MemberwiseClone do a deep copy of all base class objects ? I
doubt it. Then how do you propose to copy base class private
variables which need deep copies done ? Finally, in your own "deep
copy of objects that need special attention" you have to deep copy
all protected variables from all base classes manually. Once again,
Ugh !!! And this flawed technique is better than protected copy
constructors ?

The method in the article is broken also, unless I have missed
something subtle about MemberwiseClone.

What have I missed here ?

I think it still comes down to your, I must say odd, insistence that a
method that performs a copy is a copy constructor, and I am tired of
arguing this point, I've done it too many times.

No it comes down to the fact that the copy constructor technique, even as a
protected copy constructor called by Clone, is regular and just works. I
don't mind the method in the article working, as long as I understand it. If
it has pluses which the protected copy constructor technique does not have,
please point it out to me.
And as Jon Skeet pointed out, you shouldn't be exposing variables as
protected anyway.
Due to how MemberwiseClone works, a derivation that either doesn't
add state or that adds only generic state(that is primitives and
strings), doesn't need to handle any form of clone method.

Nor does it need to provide a protected copy constructor in my technique. It
is up to the class implementor whether cloning needs to be done on his
class.

That is not what I meant by not being cloneable however. It is a
documentation issue. The documentation for class can simple say that it is
not cloneable, meaning there is no reliable way of making a copy of this
object and retain state. Therefore all classes derived from that base are
not cloneable. Then in my derived class I don't try to make my class
cloneable.
I find
that *most* of my member variables are of primitive type, and I've
written more than one derivation class that doesn't even create a
class variable. Forcing a developer to write a clone method when he
has nothign to clone is just silly.

I agree. Nor do I want a copy constructor in that case.
Implementing implies the object
can be cloned, for proper operation you should handle that, when
nessecery, as I illustrated above, and object can choose to not
provide any clone code and stlll allow cloning.

Again agreed. In the case of copy construction, the same applies.

I haven't answered your other latest post in this thread because it gets
into personal things which are unnecessary. From Mr. Skeets explanation of
the article specified, I believe I do understand how it works using
MemberwiseClone. I still prefer my own technique using Clone and protected
copy constructors. But if there are pluses to the article which my technique
does not have, please discuss them if you like. I don't mean to get personal
in the heat of discussing a technical issue. The only thing I ask is to
please refrain from the "It's the .NET way of doing it." I don't care about
the .NET way and I don't care about the C++ way, I only care about the best
and clearest way. If there are two valid and workable ways, all the better.
 
J

Jon Skeet [C# MVP]

Edward Diener said:
Nonsense, as are all general dicta of this type ! Why not no
public/protected fields at all, just properties ? It is not a bad general
idea but there are always cases which provide exceptions, and I would rather
have freedom of implementation than straitjackets put upon me.

And of course you do have that freedom - no-one's forcing you to adhere
to coding standards I like, or even those that Microsoft suggests. The
reasons for not using public/protected fields are out of the realm of
this discussion, however - we can talk about it in another thread if
you like though.
That is true. That is why I said that using Clone() is fine, as long as one
uses protected copy constructors internally to do it.

Why should you use protected copy constructors internally to do it?
What do you have against MemberwiseClone? In fact, if you *do* use
protected copy constructors, you have a restriction that *everything*
in the type hierarchy has to have the appropriate copy constructor (or
risk losing private fields). MemberwiseClone just works.
If one does not need
polymorphic cloning, something which I have found to be a rarity in actual
practice, just using copy constructors works fine.

As does Clone. I've found *both* to be fairly rarely used myself.

So essentially only the base class in a hierarchy calls MemberwiseClone,
doing any deep copies if necessary after it, and all other classes call
their base class clone and then do deep copies as appropriate. I believe
that is the explanation I missed in the article ?

Not necessarily the base class - just the first one that implements the
Clone method. I hope this has covered any problems you expected with
MemberwiseClone.
That's fine but I find the following simpler and more regular.

In my scheme, all classes use the same method of cloning. All Clone()
methods call their own protected copy constructors. All the protected copy
constructors are responsible for calling base class protected copy
constructors and copying their own data.

So *every* class in the hierarchy has to do work, whether or not it's
actually aware of the fact that it's going to be cloned. If you have a
single class which doesn't have a copy constructor, you're stuffed. If,
however, you use MemberwiseClone you can have a type hierarchy where
you *don't* have any other requirements of the top-level class, and
where classes which don't want to change the default (shallow copy)
behaviour don't need to do anything whatsoever. To me, that's simpler.

Also, your code doesn't (in some senses) actually fulfill the contract
of ICloneable.Clone, which states:

<quote>
The resulting clone must be of the same type as or a compatible type to
the original instance.
</quote>

It only does so if the type it's invoked on is Base or Derived - if
someone else creates another derived class, then unless they override
Clone themselves, your code is broken. With MemberwiseClone it would
work automatically.
To me this is preferable to a base class doing MemberwiseClone and all other
classes calling the base class's Clone and then doing deep copies on
particular variables of the cloned object. I believe the call to
MemberwiseClone, which must involve reflection, is of greater overhead than
the simple protected copy constructor scheme I have advocated.

Why must MemberwiseClone involve reflection? I would imagine it's just
a block copy of memory, to be honest - don't forget it's implemented
deep inside the core framework, and needn't be (and almost certainly
isn't) written in IL.
 
D

Daniel O'Connell

Edward Diener said:
Daniel said:
Edward Diener said:
Daniel O'Connell wrote:
Interestingly, I just ran across an article[1] that
addresses(although in considerably less detail) this issue.
It also showed me a mistake I made, Clone does not have an issue
with an derivative skipping implementation of Clone, and this
infact shows precisely why copy constructors can't be used. For
properly polymorphic code, the Clone method should call
MemberwiseClone, which creates a shallow copy of your current
object, with the proper type. This would then be modified with deep
copy calls via a protected method as I illustrated.

Does MemberwiseClone do a deep copy of all base class objects ? I
doubt it. Then how do you propose to copy base class private
variables which need deep copies done ? Finally, in your own "deep
copy of objects that need special attention" you have to deep copy
all protected variables from all base classes manually. Once again,
Ugh !!! And this flawed technique is better than protected copy
constructors ?

The method in the article is broken also, unless I have missed
something subtle about MemberwiseClone.

What have I missed here ?

I think it still comes down to your, I must say odd, insistence that a
method that performs a copy is a copy constructor, and I am tired of
arguing this point, I've done it too many times.

No it comes down to the fact that the copy constructor technique, even as a
protected copy constructor called by Clone, is regular and just works. I
don't mind the method in the article working, as long as I understand it. If
it has pluses which the protected copy constructor technique does not have,
please point it out to me.
And as Jon Skeet pointed out, you shouldn't be exposing variables as
protected anyway.
Due to how MemberwiseClone works, a derivation that either doesn't
add state or that adds only generic state(that is primitives and
strings), doesn't need to handle any form of clone method.

Nor does it need to provide a protected copy constructor in my technique. It
is up to the class implementor whether cloning needs to be done on his
class.

That is not what I meant by not being cloneable however. It is a
documentation issue. The documentation for class can simple say that it is
not cloneable, meaning there is no reliable way of making a copy of this
object and retain state. Therefore all classes derived from that base are
not cloneable. Then in my derived class I don't try to make my class
cloneable.
I find
that *most* of my member variables are of primitive type, and I've
written more than one derivation class that doesn't even create a
class variable. Forcing a developer to write a clone method when he
has nothign to clone is just silly.

I agree. Nor do I want a copy constructor in that case.
The problem is that a perfectly clonable base object that doesn't have any
special circumstances(ie only primitives and string) *must* provide a
constructor, or if the class provides no additional state(perhaps just
provides functional overloads), with clone such a class doesn't have to do
anything. When using copy constructors, not providing a constructor freezes
copying, even though there is no reason to stop it. It places a
responsibility on an overloader to do things he is uninterested in, which is
not proper, IMHO.

This is illustrated here
using public Copy Constructors(same issues as with protected):
public class Base : ICloneable
{
public Base()
{
someInternalData = 10;
}
//copy constructor
public Base(Base b)
{
this.someInternalData = b.someInternalData;
}

int someInternalData;
public virtual void DoSomething()
{
Console.WriteLine(someInternalData);
}
//to retain type equality, this must be overloaded in every class
public virtual object Clone()
{
return new Base(this);
}

}

public class Derived : Base
{
public Derived()
{

}
//this is useless, but must exist to allow Derived to be copied
//if it is not here, SecondDerived cannot be cloned, although
//Derived has no data to clone and no reason to be concerned
//with cloning
public Derived(Derived d) : base(b)
{

}
public override void DoSomething()
{
Console.WriteLine("In DoSomething() method");
base.DoSomething ();
}
public override object Clone()
{
return new Derived(this);
}

}

public class SecondDerived : Derived
{
public SecondDerived(int anotherNumber)
{
this.anotherNumber = anotherNumber;
}
public SecondDerived(SecondDerived s) : base(s)
{
this.anotherNumber = s.anotherNumber;
}
public override void DoSomething()
{
Console.WriteLine("anotherNumber is: " + anotherNumber);
base.DoSomething ();
}

public override object Clone()
{
return new SecondDerived(this);
}

int anotherNumber;

}

using MemberwiseClone:
public class Base : ICloneable
{
public Base()
{
someInternalData = 10;
}


int someInternalData;
public virtual void DoSomething()
{
Console.WriteLine(someInternalData);
}
// this only needs to be overloaded in classs with non-primitive data
// for ease of implementation, ideally there would be a virtual
Clone(object)
// method instead of relying on every class to perform the clone for the
// entire hiearchy
public virtual object Clone()
{
return MemberwiseClone();
}

}

public class Derived : Base
{
public Derived()
{

}
public override void DoSomething()
{
Console.WriteLine("In DoSomething() method");
base.DoSomething ();
}


}

public class SecondDerived : Derived
{
public SecondDerived(int anotherNumber)
{
this.anotherNumber = anotherNumber;
}
public override void DoSomething()
{
Console.WriteLine("anotherNumber is: " + anotherNumber);
base.DoSomething ();
}
int anotherNumber;

}
Again agreed. In the case of copy construction, the same applies.

I haven't answered your other latest post in this thread because it gets
into personal things which are unnecessary. From Mr. Skeets explanation of
the article specified, I believe I do understand how it works using
MemberwiseClone. I still prefer my own technique using Clone and protected
copy constructors. But if there are pluses to the article which my technique
does not have, please discuss them if you like. I don't mean to get personal
in the heat of discussing a technical issue. The only thing I ask is to
please refrain from the "It's the .NET way of doing it." I don't care about
the .NET way and I don't care about the C++ way, I only care about the best
and clearest way. If there are two valid and workable ways, all the
better.

I can accept that you have your preferences, however I do not agree with
ignoring the platform you are on as a whole, I feel that that is
irresponsible and not conducive to writing code that is of much use to
anyone but you. You are free to write as you wish, I just ask that people
take into consideration the platform and the ideals they are working with,
its the only way any of this stuff will ever work together.

We have a difference in opinoin here, however. Two valid and workable
methods is ok, but just allowing people to do what they wish generally
isn't. If I have to guess as to your intentions, and you as to mine, that
breaks down any chances of intercommunication between our code.
When I look at commerical .NET libriares, the first thing I look for is
proper, non-language specific interface. I have recommended against buying a
library for something as simple as exposing a _ prefixed field, or for
providing only optional arguments instead of overloads. I consider *public*
copy constructors or protected constructors in classes I may wish to inherit
from to be something of an issue here, because it ignores the standard
way(ie ICloneable and MemberwiseClone), I will dismiss that code and find
something that is going to work with everything else. When I write .NET
code, I write .NET code, not managed C++, not VB.NET, not C#, but code for
the .NET platform. I try to use constructs that are standard and something
that every developer who is familiar with the framework will grasp.
ICloneable and MemberwiseClone are at the core of the framework and are
something that every well versed user should be aware of(and when done
properly, MemberwiseClone is irrelevent to the inheritor), copy constructors
are something I wouldn't expect anyone to know about at first glance. I do
feel there is a considerable difference in obviousness between Base(Base b)
and Base.Clone(). Someone who hasn't used copy constructors is not going to
be able to reasonably guess waht the former does, however the latter lends
itself to understanding. You may argue that the name and the function may
not coincide, but I argue that in proper code they should. In which case the
obvious, clear virtual method is arguably a better choice than the one that
requires knowledge of a language or technique that isn't widespread within
the current system.
 
E

Edward Diener

Jon said:
Why should you use protected copy constructors internally to do it?
What do you have against MemberwiseClone? In fact, if you *do* use
protected copy constructors, you have a restriction that *everything*
in the type hierarchy has to have the appropriate copy constructor (or
risk losing private fields). MemberwiseClone just works.

OK, you have a good point. If my class doesn't need deep copying, I don't
need to implement a Clone() whereas I still do need to implement a protected
copy constructor in my scheme in .NET. In C++, if one does not provide a
copy constructor, a default copy constructor is created which works just
like MemberwiseClone in that it does a shallow copy of the member data. So
it is not necessary there to do one's own copy construction if all I need is
a shallow copy, which mimics your technique. In .NET this doesn't happen so
you have a good point in going with the Clone chaining and MemberwiseClone
technique at the base class.

The disadvantage which I see to your method is that one must know whether a
base class has already implemented MemberwiseClone in order to decide to
implement one's own Clone as either 1) MemberwiseClone followed by deep
copies or 2) base.Clone followed by deep copies. This to me means that one
has to simply know whether a base class has implemented Clone or not. If a
base class has implemented Clone your implementation calls the base class
Clone before doing any deep copying. If a base class has not implemented
Clone, your implementation does a MemberwiseClone before doing any deep
copy. N'est-ce pas, or did I miss something in this ? Of course
documentation will tell whether some base class has already implemented
Clone or not. But still it is something one needs to know as far as I can
see.
As does Clone. I've found *both* to be fairly rarely used myself.
Agreed.


Not necessarily the base class - just the first one that implements
the Clone method. I hope this has covered any problems you expected
with MemberwiseClone.




So *every* class in the hierarchy has to do work, whether or not it's
actually aware of the fact that it's going to be cloned. If you have a
single class which doesn't have a copy constructor, you're stuffed.

True in .NET, not true in C++. See above.
If, however, you use MemberwiseClone you can have a type hierarchy
where you *don't* have any other requirements of the top-level class,
and where classes which don't want to change the default (shallow
copy) behaviour don't need to do anything whatsoever. To me, that's
simpler.

Also, your code doesn't (in some senses) actually fulfill the contract
of ICloneable.Clone, which states:

<quote>
The resulting clone must be of the same type as or a compatible type
to the original instance.
</quote>

It only does so if the type it's invoked on is Base or Derived - if
someone else creates another derived class, then unless they override
Clone themselves, your code is broken. With MemberwiseClone it would
work automatically.

That's true but I would always expect a class deriving from a cloneable
class to implement Clone if they were using my copy constructor method.
Why must MemberwiseClone involve reflection? I would imagine it's just
a block copy of memory, to be honest - don't forget it's implemented
deep inside the core framework, and needn't be (and almost certainly
isn't) written in IL.

You are correct. Just copying the memory is good enough. It just has to
figure out where the memory for the object begins and ends.

You have made a good case for using the Clone technique in .NET with
MemberwiseClone at the lowest Clone level. Essentially it does what C++ does
in guaranteeing that if a class has no copy constructor, a default one doing
a shallow copy is generated, but in a .NET way. I appreciate the discussion,
which has clarified the use of Clone for me. I hadn't really realized before
the implication that calling down the Clone hierarchy would work correctly
to build an object on which I could do deep copies. I think my proviso still
holds with the mentioned technique, that one must know whether there is a
real Clone implemented by one's base class before deciding whether to call
down or implement MemberwiseClone oneself. That is something in C++'s scheme
of copy constrcuctors/default copy constructors which one does not have to
worry about, but in .NET default copy constructors are not provided. For my
own class hierarchy I could use C++'s copy constructor scheme as long as I
made sure that all my .NET classes provided their own copy constructor, but
the .NET way is better in .NET since it allows one to not provide a Clone
when only shallow copyin is necessary.
 
E

Edward Diener

Daniel said:
The problem is that a perfectly clonable base object that doesn't
have any special circumstances(ie only primitives and string) *must*
provide a constructor, or if the class provides no additional
state(perhaps just provides functional overloads), with clone such a
class doesn't have to do anything. When using copy constructors, not
providing a constructor freezes copying, even though there is no
reason to stop it. It places a responsibility on an overloader to do
things he is uninterested in, which is not proper, IMHO.

It's two against one, you and Mr. Skeet. Unfair <g> .

I have answered Mr. Skeet on this but I will answer you also. You are
correct about this in .NET. In C++ a class not implementing a copy
constructor is given one which does a shallow copy. But you are right about
..NET and this supports the Clone/MemberwiseClone technique.
snipped...

I can accept that you have your preferences, however I do not agree
with ignoring the platform you are on as a whole, I feel that that is
irresponsible and not conducive to writing code that is of much use to
anyone but you. You are free to write as you wish, I just ask that
people take into consideration the platform and the ideals they are
working with, its the only way any of this stuff will ever work
together.

I have no problem with that. This discussion with both you and Mr. Skeet is
an attempt to understand by me how .NET implements copying and whether it is
better than what I have usually done.
We have a difference in opinoin here, however. Two valid and workable
methods is ok, but just allowing people to do what they wish generally
isn't. If I have to guess as to your intentions, and you as to mine,
that breaks down any chances of intercommunication between our code.
When I look at commerical .NET libriares, the first thing I look for
is proper, non-language specific interface. I have recommended
against buying a library for something as simple as exposing a _
prefixed field, or for providing only optional arguments instead of
overloads. I consider *public* copy constructors or protected
constructors in classes I may wish to inherit from to be something of
an issue here, because it ignores the standard way(ie ICloneable and
MemberwiseClone), I will dismiss that code and find something that is
going to work with everything else. When I write .NET code, I write
.NET code, not managed C++, not VB.NET, not C#, but code for the .NET
platform. I try to use constructs that are standard and something
that every developer who is familiar with the framework will grasp.
ICloneable and MemberwiseClone are at the core of the framework and
are something that every well versed user should be aware of(and when
done properly, MemberwiseClone is irrelevent to the inheritor), copy
constructors are something I wouldn't expect anyone to know about at
first glance. I do feel there is a considerable difference in
obviousness between Base(Base b) and Base.Clone(). Someone who hasn't
used copy constructors is not going to be able to reasonably guess
waht the former does, however the latter lends itself to
understanding. You may argue that the name and the function may not
coincide, but I argue that in proper code they should. In which case
the obvious, clear virtual method is arguably a better choice than
the one that requires knowledge of a language or technique that isn't
widespread within the current system.

I am always willing to do things the .NET way, as long as I feel it works
and is as good or better than what I have done in the past. If it is not, I
use what I know, even if it is not the standard way of doing things but is
easily understandable to others. I do work largely in the area of component
development, so I am aware of trying to follow standards which others
understand. Now that I understand Clone/MemberwiseClone I see that it can
work and only provides a single proviso which makes it more difficult than
the C++ copy constructor technique, while providing polymorphism and the
ability not to have to provide a Clone if all one has is shallow copied
members.

The one proviso, which admittedly is a small one, is that if one does
implement Clone, one must know whether some base class has implemented
Clone. If a base class has, one calls done to its Clone before doing any
deep copying, whereas if it hasn't one does a MemberwiseClone before doing
deep copying. But this is just documentation and no big deal, since if a
base class already implements ICloneable, somewhere a base class has to have
implemented Clone. So it comes out to: if I am the first class in the
hierarchy to implement ICloneable, I call MemberwiseClone before doing any
deep copies if necessary, while if I am not the first class in the hierarchy
to implement ICloneable and I implement Clone, I call down to my base
class's Clone before doing deep copies. That's not too bad even if I still
think it is less elegant than copy constructors <g> .
 
D

Daniel O'Connell

Edward Diener said:
It's two against one, you and Mr. Skeet. Unfair <g> .
Ya, I replied before I read his post in much seriousness, or I wouldn't have
posted the same arguments again, ;)
I have answered Mr. Skeet on this but I will answer you also. You are
correct about this in .NET. In C++ a class not implementing a copy
constructor is given one which does a shallow copy. But you are right about
.NET and this supports the Clone/MemberwiseClone technique.


I have no problem with that. This discussion with both you and Mr. Skeet is
an attempt to understand by me how .NET implements copying and whether it is
better than what I have usually done.


I am always willing to do things the .NET way, as long as I feel it works
and is as good or better than what I have done in the past. If it is not, I
use what I know, even if it is not the standard way of doing things but is
easily understandable to others. I do work largely in the area of component
development, so I am aware of trying to follow standards which others
understand. Now that I understand Clone/MemberwiseClone I see that it can
work and only provides a single proviso which makes it more difficult than
the C++ copy constructor technique, while providing polymorphism and the
ability not to have to provide a Clone if all one has is shallow copied
members.

The one proviso, which admittedly is a small one, is that if one does
implement Clone, one must know whether some base class has implemented
Clone. If a base class has, one calls done to its Clone before doing any
deep copying, whereas if it hasn't one does a MemberwiseClone before doing
deep copying. But this is just documentation and no big deal, since if a
base class already implements ICloneable, somewhere a base class has to have
implemented Clone. So it comes out to: if I am the first class in the
hierarchy to implement ICloneable, I call MemberwiseClone before doing any
deep copies if necessary, while if I am not the first class in the hierarchy
to implement ICloneable and I implement Clone, I call down to my base
class's Clone before doing deep copies. That's not too bad even if I still
think it is less elegant than copy constructors <g> .
Which is part of why I prefer to use a common virtual Clone method and an
override, instead of relying on clone. An issue with Clone is
ICloneable.Clone may be implemented as an explicit implementaion or as a
different name(such as in VB), and MyObject.Clone and
((ICloneable)myObject).Clone may be different methods. Also, an explicit
implementation will bypass the polymorphism. Because of this I prefer to
implement IClonable on the base which performs Memberwise Clone and have it
call a virtual method in the pattern I showed before, rather than rely on
overrides of clone determining if MemberwiseClone has been performed.
 
E

Edward Diener

Daniel said:
Which is part of why I prefer to use a common virtual Clone method
and an override, instead of relying on clone. An issue with Clone is
ICloneable.Clone may be implemented as an explicit implementaion or
as a different name(such as in VB), and MyObject.Clone and
((ICloneable)myObject).Clone may be different methods. Also, an
explicit implementation will bypass the polymorphism. Because of this
I prefer to implement IClonable on the base which performs Memberwise
Clone and have it call a virtual method in the pattern I showed
before, rather than rely on overrides of clone determining if
MemberwiseClone has been performed.

That should work fine but I think it is not standard, since derived class
need to know to implement your virtual method rather than ICloneable.Clone.
Nor is there anything to keep classes who have derived from yours from
implementing your own virtual method as something else in the same way that
they might implement Clone as something else, other than documentation of
course. Anyway I think all the rest is a moot point, really. I do understand
the Clone/MemeberwiseClone method and see that it does work as long as one
follows its way of doing cloning.

In straight C++ I will stick with copy constructors, but if I do implement a
polymorphic clone myself in C++ I now see that I can use the copy
constructors with it. This is because standard C++ guarantees default copy
constructors if one does not do one's own. But in .NET the
Clone/MemeberwiseClone is better because it requires no work when one
doesn't need to implement Clone but can rely on the MemberwiseClone default.
In essence, MemberwiseClone provides the same guarantees as default
constructors do in C++, just as long as one remembers to implement it at the
original ICloneable level.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top