By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,412 Members | 2,896 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,412 IT Pros & Developers. It's quick & easy.

Copy constructors and clones

P: n/a
Coming from the C++ world I can not understand the reason why copy
constructors are not used in the .NET framework. A copy constructor creates
an object from a copy of another object of the same kind. It sounds simple
but evidently .NET has difficulty with this concept for some reason. I do
understand that .NET objects are created on the GC heap but that doesn't
mean that they couldn't be copied from another object of the same kind when
they are created.

I understand that .NET has an ICloneable interface which is used to make a
deep copy of an object, and that it even has a protected MemberWiseClone to
be used internally for shallow copies. But much to my surprise even
ICloneable.Clone() is sometimes not used to make a deep copy of an object
but some other particular class member function is used instead.

As an example when I look at the system.string class I find that it does not
have a copy constructor, which for whatever reason I do not understand seems
normal for .NET. Then I look at the Clone() function, expecting it to make a
copy of the string's contents and return it to me as a new string. No, it
doesn't do that either. Finally I find the Copy() function which does the
job. So instead of creating a new string from an old one, I must do the
arcane ( for me ) 'string x = string.Copy(old_instance);' rather than a
simple 'string x = new string(old_instance)'.

Comments and explanations ?
Jul 21 '05 #1
Share this Question
Share on Google+
42 Replies


P: n/a
Cor
Hi Edward

VB.net
dim newstring as string = oldstring
C#
string newstring = oldstring;
C++ as you said
string newstring = new string(oldstring)

I think you love to type?

Comments:

Never try to use your used old statements from you used language.

Example, once someone told me that in his language he only used 50 code for
a sort, he had translated it to the one I was using then and he 200 lines of
code

He had not seen that there was a statemen "sort" from one line.
(It was also much faster)

Cor

Coming from the C++ world I can not understand the reason why copy
constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same kind. It sounds simple
but evidently .NET has difficulty with this concept for some reason. I do
understand that .NET objects are created on the GC heap but that doesn't
mean that they couldn't be copied from another object of the same kind when they are created.

I understand that .NET has an ICloneable interface which is used to make a
deep copy of an object, and that it even has a protected MemberWiseClone to be used internally for shallow copies. But much to my surprise even
ICloneable.Clone() is sometimes not used to make a deep copy of an object
but some other particular class member function is used instead.

As an example when I look at the system.string class I find that it does not have a copy constructor, which for whatever reason I do not understand seems normal for .NET. Then I look at the Clone() function, expecting it to make a copy of the string's contents and return it to me as a new string. No, it
doesn't do that either. Finally I find the Copy() function which does the
job. So instead of creating a new string from an old one, I must do the
arcane ( for me ) 'string x = string.Copy(old_instance);' rather than a
simple 'string x = new string(old_instance)'.

Comments and explanations ?

Jul 21 '05 #2

P: n/a
> As an example when I look at the system.string class I find that it does
not
have a copy constructor, which for whatever reason I do not understand seems normal for .NET. Then I look at the Clone() function, expecting it to make a copy of the string's contents and return it to me as a new string. No, it
doesn't do that either. Finally I find the Copy() function which does the
job. So instead of creating a new string from an old one, I must do the
arcane ( for me ) 'string x = string.Copy(old_instance);' rather than a
simple 'string x = new string(old_instance)'.


Strings are immutable. So you are basically wasting memory if you copy them.
Copying is only interesting if you can get a mutable copy.

Bruno.

Jul 21 '05 #3

P: n/a
Cor wrote:
Hi Edward

VB.net
dim newstring as string = oldstring
C#
string newstring = oldstring;
This assigns the reference of the oldstring to the newstring. It does not do
a copy.
C++ as you said
string newstring = new string(oldstring)
Wrong syntax. It would have to be:

String * newstring = new String(oldstring);

I don't see a constructor like this in the documentation. Does it really
exist for making a copy ? If so it is not documented.

I think you love to type?
No, I hate to type. That is why I brought up the subject in the first place.
I also find copy constructors easy to use in C++. However the example you
gave for C# does not do a copy and the corrected example for C++ does not
exist AFAIK. I don't know VB but I am guessing that it doesn't do a copy
either but rather creates another reference.

Comments:

Never try to use your used old statements from you used language.

Example, once someone told me that in his language he only used 50
code for a sort, he had translated it to the one I was using then and
he 200 lines of code

He had not seen that there was a statemen "sort" from one line.
(It was also much faster)

Cor

Coming from the C++ world I can not understand the reason why copy
constructors are not used in the .NET framework. A copy constructor
creates an object from a copy of another object of the same kind. It
sounds simple but evidently .NET has difficulty with this concept
for some reason. I do understand that .NET objects are created on
the GC heap but that doesn't mean that they couldn't be copied from
another object of the same kind when they are created.

I understand that .NET has an ICloneable interface which is used to
make a deep copy of an object, and that it even has a protected
MemberWiseClone to be used internally for shallow copies. But much
to my surprise even ICloneable.Clone() is sometimes not used to make
a deep copy of an object but some other particular class member
function is used instead.

As an example when I look at the system.string class I find that it
does not have a copy constructor, which for whatever reason I do not
understand seems normal for .NET. Then I look at the Clone()
function, expecting it to make a copy of the string's contents and
return it to me as a new string. No, it doesn't do that either.
Finally I find the Copy() function which does the job. So instead of
creating a new string from an old one, I must do the arcane ( for me
) 'string x = string.Copy(old_instance);' rather than a simple
'string x = new string(old_instance)'.

Comments and explanations ?

Jul 21 '05 #4

P: n/a
Cor,

As a string is a reference type, "dim newstring as string = oldstring"
causes "newstring" to point to the same string instance as "oldstring" (as
can be demonstrated by the Is operator). Some may mistakenly think that they
point to different instances because if you change "newstring", "oldstring"
doesn't change - this is because a string is immutable, not because there
are two string instances containing the same characters. If you done this
with an object that is not immutable, then it is not a copy, simply another
reference to the same object (unless you use a value type).

Back to Edwards question, I think that the lack of copy constructors in .net
is more of an oversight in the implementation of the object that you are
using, rather than a missing feature in the languages. Personally, I think
ICloneable is suitable - afterall not all objects can be cloned - those that
can't be cloned simply do not implement ICloneable. Also, there is nothing
to stop you implementing a copy constructor in your own objects.

As far as the documentation for the Clone method of a string is concerned it
states:

"The return value is not an independent copy of this instance; it is simply
another view of the same data. Use the Copy or CopyTo method to create a
separate String object with the same value as this instance."

Which kinda defeats the purpose of the Clone method in my opinion, but I
guess they had their reasons (probably because a string is immutable, so
changes will not affect other references to the same instance).

HTH,

Trev.
Jul 21 '05 #5

P: n/a
Edward,
In addition to Cor's comments.

There is nothing stopping you from defining a copy constructor in your
classes! In fact I use (protected) copy constructors to implement my Clone
methods in one of my projects, as you have to if you want to use read-only
fields in your class. :-) Read-only fields can only be set in the
constructor, MemberWiseCopy was not an option as I need a deep copy...

IMHO The biggest advantage that the Clone Pattern has over copy constructors
is that the Clone pattern can be polymorphic. You can define Clone as
virtual/overridable in the base class, and offer implementation in the
derived classes. The other code can create a copy of that object, with only
a reference to the base object!

IMHO The second biggest advantage is consistency. If you need Clone for
polymorphism, having some classes implement clone while others implement
pure copy constructors leads to somewhat inconsistent code. Having all
objects that can be 'copied' implement the Clone pattern leads to code that
is quicker to understand (unless of course you can from a C++ background
;-)). Note some classes support Clone & Copy methods. Where Clone does a
"shallow" copy, while Copy does a "deep" copy. In addition to your String
example see System.Data.DataSet & System.Data.DataTable for examples.

IMHO the one danger of copy constructors are in class hierarchies like
System.IO.Stream. Is the stream object passed to the constructor of a
derived stream intended for a copy or are you implementing a
Composite/Delegate Pattern?

I want to say there are a handful of classes in the Framework that support
copy constructors, however I don't remember specifically which ones.
As an example when I look at the system.string class I find that it does not
Remember that String is immutable reference type, I have yet to need to make
a copy of the contents of a string. I would do as Cor stated.

String x = old_instance

And live with the reference. In fact I would prefer to have the reference,
as it performs better & is easier on Memory consumption...

Hope this helps
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2***************@tk2msftngp13.phx.gbl... Coming from the C++ world I can not understand the reason why copy
constructors are not used in the .NET framework. A copy constructor creates an object from a copy of another object of the same kind. It sounds simple
but evidently .NET has difficulty with this concept for some reason. I do
understand that .NET objects are created on the GC heap but that doesn't
mean that they couldn't be copied from another object of the same kind when they are created.

I understand that .NET has an ICloneable interface which is used to make a
deep copy of an object, and that it even has a protected MemberWiseClone to be used internally for shallow copies. But much to my surprise even
ICloneable.Clone() is sometimes not used to make a deep copy of an object
but some other particular class member function is used instead.

As an example when I look at the system.string class I find that it does not have a copy constructor, which for whatever reason I do not understand seems normal for .NET. Then I look at the Clone() function, expecting it to make a copy of the string's contents and return it to me as a new string. No, it
doesn't do that either. Finally I find the Copy() function which does the
job. So instead of creating a new string from an old one, I must do the
arcane ( for me ) 'string x = string.Copy(old_instance);' rather than a
simple 'string x = new string(old_instance)'.

Comments and explanations ?

Jul 21 '05 #6

P: n/a
Bruno Jouhier [MVP] wrote:
As an example when I look at the system.string class I find that it
does not have a copy constructor, which for whatever reason I do not
understand seems normal for .NET. Then I look at the Clone()
function, expecting it to make a copy of the string's contents and
return it to me as a new string. No, it doesn't do that either.
Finally I find the Copy() function which does the job. So instead of
creating a new string from an old one, I must do the arcane ( for me
) 'string x = string.Copy(old_instance);' rather than a simple
'string x = new string(old_instance)'.


Strings are immutable. So you are basically wasting memory if you
copy them. Copying is only interesting if you can get a mutable copy.


You are correct. Definitely my error for not realizing this.
Jul 21 '05 #7

P: n/a
Codemonkey wrote:
Cor,

As a string is a reference type, "dim newstring as string = oldstring"
causes "newstring" to point to the same string instance as
"oldstring" (as can be demonstrated by the Is operator). Some may
mistakenly think that they point to different instances because if
you change "newstring", "oldstring" doesn't change - this is because
a string is immutable, not because there are two string instances
containing the same characters. If you done this with an object that
is not immutable, then it is not a copy, simply another reference to
the same object (unless you use a value type).
Yes, what I said in my reply. You gave an example of a reference assignment
and not a copy.

Back to Edwards question, I think that the lack of copy constructors
in .net is more of an oversight in the implementation of the object
that you are using, rather than a missing feature in the languages.
IMHO copy constructors are an easy way to construct a new object from an old
object of the same type.
Personally, I think ICloneable is suitable - afterall not all objects
can be cloned - those that can't be cloned simply do not implement
ICloneable.
And if an object is not cloneable, .NET objects should not implement a copy
constructor. The same argument holds.
Also, there is nothing to stop you implementing a copy
constructor in your own objects.
Of course not, but why the .NET framework objects don't have them was the
original query.

As far as the documentation for the Clone method of a string is
concerned it states:

"The return value is not an independent copy of this instance; it is
simply another view of the same data. Use the Copy or CopyTo method
to create a separate String object with the same value as this
instance."

Which kinda defeats the purpose of the Clone method in my opinion,
but I guess they had their reasons (probably because a string is
immutable, so changes will not affect other references to the same
instance).


I was wrong to bring up string. Since it is immutable, making a copy of it
is a waste of time. I now realize this. But having copy constructors for
mutable objects still seems like a good idea to me and I am still surprised
mutable FCL classes do not have them.
Jul 21 '05 #8

P: n/a
Jay B. Harlow [MVP - Outlook] wrote:
Edward,
In addition to Cor's comments.

There is nothing stopping you from defining a copy constructor in your
classes!
Of course not.
In fact I use (protected) copy constructors to implement my
Clone methods in one of my projects, as you have to if you want to
use read-only fields in your class. :-) Read-only fields can only be
set in the constructor, MemberWiseCopy was not an option as I need a
deep copy...
I agree.

IMHO The biggest advantage that the Clone Pattern has over copy
constructors is that the Clone pattern can be polymorphic. You can
define Clone as virtual/overridable in the base class, and offer
implementation in the derived classes. The other code can create a
copy of that object, with only a reference to the base object!
I don't see how ICloneable::Clone being polymorphic helps at all. Can you
give me an example ? I find it exactly otherwise and I see it hindering
things since I can not use the cloned object of a base class in my derived
class Clone(), since the base class
Clone() creates a separate object reference to the base class for me and yet
my derived class's Clone() has to return a reference to my derived class. So
in my Clone() for a derived class I must repeat everything I am doing in my
base class's Clone() plus any member variables that need to be cloned for my
derived class.

OTOH copy constructors have no such problems and are actually polymorphic by
nature. If my base class has a copy constructor, I simply call the base
class copy constructor passing the other object that needs to be copied to
the base class, then I copy any other non-base fields from the copied object
to my own. This is much easier and more natural than implementing Clone() in
a class hierarchy.

IMHO The second biggest advantage is consistency. If you need Clone
for polymorphism, having some classes implement clone while others
implement pure copy constructors leads to somewhat inconsistent code.
I can understand this as an inconsistency but I would rather have copy
constructors than cloneable objects ( see above ). The one advantage of
ICloneable as an interface is that one can test for it in code to see if an
object is cloneable. But I see little advantage for this at run-time.
Having all objects that can be 'copied' implement the Clone pattern
leads to code that is quicker to understand (unless of course you can
from a C++ background ;-)).
The smiley is noted. For C++ programmers copy constructors are much easier
to use and program. I still think they are in any application framework.
Note some classes support Clone & Copy
methods. Where Clone does a "shallow" copy, while Copy does a "deep"
copy. In addition to your String example see System.Data.DataSet &
System.Data.DataTable for examples.
Yes, now that is confusing <g> .

IMHO the one danger of copy constructors are in class hierarchies like
System.IO.Stream. Is the stream object passed to the constructor of a
derived stream intended for a copy or are you implementing a
Composite/Delegate Pattern?
That is what documentation is all about. Normally the same object passed to
a copy constructor is always for copy however. If you need a composite, the
object can be passed in a member function.

I want to say there are a handful of classes in the Framework that
support copy constructors, however I don't remember specifically
which ones.
There may be some AFAIK but generally FCL does not support the idea of copy
constructors. Which is something I find a bit strange.
As an example when I look at the system.string class I find that it
does not
Remember that String is immutable reference type, I have yet to need
to make a copy of the contents of a string. I would do as Cor stated.

String x = old_instance

And live with the reference. In fact I would prefer to have the
reference, as it performs better & is easier on Memory consumption...


This was definitely my mistake in using an immutable object as an example.
String doesn't need a copy constructor and even the String::Copy member
function seems a waste of time to me.

Hope this helps
Except for the ICloneable interface telling code at run-time that an object
is cloneable, I don't see eveidence that it is preferable to copy
constructors and all my experience points the other way. I will be glad to
look at evidence which favors ICloneable if you would like to present it.
Sometimes older, time-tested ideas are best.
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2***************@tk2msftngp13.phx.gbl...
Coming from the C++ world I can not understand the reason why copy
constructors are not used in the .NET framework. A copy constructor
creates an object from a copy of another object of the same kind. It
sounds simple but evidently .NET has difficulty with this concept
for some reason. I do understand that .NET objects are created on
the GC heap but that doesn't mean that they couldn't be copied from
another object of the same kind when they are created.

I understand that .NET has an ICloneable interface which is used to
make a deep copy of an object, and that it even has a protected
MemberWiseClone to be used internally for shallow copies. But much
to my surprise even ICloneable.Clone() is sometimes not used to make
a deep copy of an object but some other particular class member
function is used instead.

As an example when I look at the system.string class I find that it
does not have a copy constructor, which for whatever reason I do not
understand seems normal for .NET. Then I look at the Clone()
function, expecting it to make a copy of the string's contents and
return it to me as a new string. No, it doesn't do that either.
Finally I find the Copy() function which does the job. So instead of
creating a new string from an old one, I must do the arcane ( for me
) 'string x = string.Copy(old_instance);' rather than a simple
'string x = new string(old_instance)'.

Comments and explanations ?

Jul 21 '05 #9

P: n/a
Cor
Hi Edward,
This was definitely my mistake in using an immutable object as an example.
String doesn't need a copy constructor and even the String::Copy member
function seems a waste of time to me.


And therefore I was so fast with my answer, with a smile on my face when I
was writting it.

:-))

Cor
Jul 21 '05 #10

P: n/a
Edward,
OTOH copy constructors have no such problems and are actually polymorphic by nature. If my base class has a copy constructor, I simply call the base
class copy constructor passing the other object that needs to be copied to
the base class, then I copy any other non-base fields from the copied object to my own. This is much easier and more natural than implementing Clone() in a class hierarchy.
Can you give a C++ example seem to be missing something in your explanation.
It may be my just being away from C++ too long. ;-)

With a copy constructor: If I have an object that is actually type Derived
in a Base variable, to create a copy of Derived I would need to call new
Derived(oldBase). correct?

// Given:
// Consider that new Derived may have come from a factory method
Base oldBase = new Derived();

// elsewhere where we don't know what the concrete type of oldBase is:
// What do you put for the new type in the following statement?
// considering that I want the exact same type back?
Base copyBase = new ????(oldBase);

With the Clone pattern I can simply call the Clone method, having defined
Clone method as virtual in Base & Derived.

Base copyBase = oldBase.Clone();
// copyBase will still be a Derived object.

The Clone method itself acts as the Factory Method to ensure the correct
type of derived object is created.
Having all objects that can be 'copied' implement the Clone pattern
leads to code that is quicker to understand (unless of course you can
from a C++ background ;-)).


The smiley is noted. For C++ programmers copy constructors are much easier
to use and program. I still think they are in any application framework.

When I programmed in C++ I would have agreed with you! Now I think I'm so
use to them not being available in Java or .NET that I really don't miss
them. However I do consider myself fortunate to have used them in C++ to be
able to apply them to good use in my class families (in Java or .NET).

Hope this helps
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:OO**************@TK2MSFTNGP12.phx.gbl... Jay B. Harlow [MVP - Outlook] wrote:
Edward,
In addition to Cor's comments.

There is nothing stopping you from defining a copy constructor in your
classes!
Of course not.
In fact I use (protected) copy constructors to implement my
Clone methods in one of my projects, as you have to if you want to
use read-only fields in your class. :-) Read-only fields can only be
set in the constructor, MemberWiseCopy was not an option as I need a
deep copy...


I agree.

IMHO The biggest advantage that the Clone Pattern has over copy
constructors is that the Clone pattern can be polymorphic. You can
define Clone as virtual/overridable in the base class, and offer
implementation in the derived classes. The other code can create a
copy of that object, with only a reference to the base object!


I don't see how ICloneable::Clone being polymorphic helps at all. Can you
give me an example ? I find it exactly otherwise and I see it hindering
things since I can not use the cloned object of a base class in my derived
class Clone(), since the base class
Clone() creates a separate object reference to the base class for me and

yet my derived class's Clone() has to return a reference to my derived class. So in my Clone() for a derived class I must repeat everything I am doing in my base class's Clone() plus any member variables that need to be cloned for my derived class.

OTOH copy constructors have no such problems and are actually polymorphic by nature. If my base class has a copy constructor, I simply call the base
class copy constructor passing the other object that needs to be copied to
the base class, then I copy any other non-base fields from the copied object to my own. This is much easier and more natural than implementing Clone() in a class hierarchy.

IMHO The second biggest advantage is consistency. If you need Clone
for polymorphism, having some classes implement clone while others
implement pure copy constructors leads to somewhat inconsistent code.
I can understand this as an inconsistency but I would rather have copy
constructors than cloneable objects ( see above ). The one advantage of
ICloneable as an interface is that one can test for it in code to see if

an object is cloneable. But I see little advantage for this at run-time.
Having all objects that can be 'copied' implement the Clone pattern
leads to code that is quicker to understand (unless of course you can
from a C++ background ;-)).
The smiley is noted. For C++ programmers copy constructors are much easier
to use and program. I still think they are in any application framework.
Note some classes support Clone & Copy
methods. Where Clone does a "shallow" copy, while Copy does a "deep"
copy. In addition to your String example see System.Data.DataSet &
System.Data.DataTable for examples.


Yes, now that is confusing <g> .

IMHO the one danger of copy constructors are in class hierarchies like
System.IO.Stream. Is the stream object passed to the constructor of a
derived stream intended for a copy or are you implementing a
Composite/Delegate Pattern?


That is what documentation is all about. Normally the same object passed

to a copy constructor is always for copy however. If you need a composite, the object can be passed in a member function.

I want to say there are a handful of classes in the Framework that
support copy constructors, however I don't remember specifically
which ones.
There may be some AFAIK but generally FCL does not support the idea of

copy constructors. Which is something I find a bit strange.
As an example when I look at the system.string class I find that it
does not
Remember that String is immutable reference type, I have yet to need
to make a copy of the contents of a string. I would do as Cor stated.

String x = old_instance

And live with the reference. In fact I would prefer to have the
reference, as it performs better & is easier on Memory consumption...


This was definitely my mistake in using an immutable object as an example.
String doesn't need a copy constructor and even the String::Copy member
function seems a waste of time to me.

Hope this helps


Except for the ICloneable interface telling code at run-time that an

object is cloneable, I don't see eveidence that it is preferable to copy
constructors and all my experience points the other way. I will be glad to
look at evidence which favors ICloneable if you would like to present it.
Sometimes older, time-tested ideas are best.
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2***************@tk2msftngp13.phx.gbl...
Coming from the C++ world I can not understand the reason why copy
constructors are not used in the .NET framework. A copy constructor
creates an object from a copy of another object of the same kind. It
sounds simple but evidently .NET has difficulty with this concept
for some reason. I do understand that .NET objects are created on
the GC heap but that doesn't mean that they couldn't be copied from
another object of the same kind when they are created.

I understand that .NET has an ICloneable interface which is used to
make a deep copy of an object, and that it even has a protected
MemberWiseClone to be used internally for shallow copies. But much
to my surprise even ICloneable.Clone() is sometimes not used to make
a deep copy of an object but some other particular class member
function is used instead.

As an example when I look at the system.string class I find that it
does not have a copy constructor, which for whatever reason I do not
understand seems normal for .NET. Then I look at the Clone()
function, expecting it to make a copy of the string's contents and
return it to me as a new string. No, it doesn't do that either.
Finally I find the Copy() function which does the job. So instead of
creating a new string from an old one, I must do the arcane ( for me
) 'string x = string.Copy(old_instance);' rather than a simple
'string x = new string(old_instance)'.

Comments and explanations ?


Jul 21 '05 #11

P: n/a
Jay B. Harlow [MVP - Outlook] wrote:
Edward,
OTOH copy constructors have no such problems and are actually
polymorphic by nature. If my base class has a copy constructor, I
simply call the base class copy constructor passing the other object
that needs to be copied to the base class, then I copy any other
non-base fields from the copied object to my own. This is much
easier and more natural than implementing Clone() in a class
hierarchy.
Can you give a C++ example seem to be missing something in your
explanation. It may be my just being away from C++ too long. ;-)


In standard C++:

class Base
{
public:
int i;
Base() { i = 0; }
Base(const Base & b) { i = b.i; }
};

class Derived : public Base
{
public:
double db;
Derived() { db = 1.0; }
Derived(const Derived & d) : Base(d) { db = d.db; }
};

Derived dfirst; // Default constructor
Derived dsecond(dfirst); // Copy constructor

When you invoke Derived's copy constructor, it passes the reference to
Base's copy constructor. Since a Derived contains a Base, there is no
problem for Base initializing its own variable(s) from that copy. The
compiler automatically downcasts from a Derived reference to a Base
reference when passing copy constructors down the chain.

With a copy constructor: If I have an object that is actually type
Derived in a Base variable, to create a copy of Derived I would need
to call new Derived(oldBase). correct?
No, see above.

// Given:
// Consider that new Derived may have come from a factory method
Base oldBase = new Derived();
In C++ this is:

Base * oldBase = new Derived();

// elsewhere where we don't know what the concrete type of oldBase is:
// What do you put for the new type in the following statement?
// considering that I want the exact same type back?
Base copyBase = new ????(oldBase);
If you do:

Base * copyBase = new Derived(*oldBase);

you get a compiler error since you are passing a reference to a base and the
Derived's copy constructor expects a reference to a Derived. If you do:

Base * copyBase = new Derived(dynamic_cast<Derived &>(*oldBase));

you are fine as long as oldBase is really pointing to a derived object. If
it is not, that is your fault and you will get a bad_cast exception thrown.
The Derived class's copy constructor above expects a Derived object. Of
course you can add another copy constructor to Derived that takes a 'const
Base &' like this:

Derived(const Base & b) : Base(b) { db = 1.0; }

and now you are successful doing:

Base * copyBase = new Derived(*oldBase);

and then you can pass Base or Derived references to it. In this sense C++
copy constructors are not polymorphic, and I shouldn't have said that. It
was bad wording and the word polymorphic was wrong. C++ constructors are not
virtual and work on the static type, not the dynamic type. What I meant to
say is that derived class objects can be passed down to base class copy
constructors through automatic downcasting. I consider this much better in
this particular case than polymorphism.

With the Clone pattern I can simply call the Clone method, having
defined Clone method as virtual in Base & Derived.

Base copyBase = oldBase.Clone();
// copyBase will still be a Derived object.
You can create a base object from a derived copy also.

Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast from a
derived reference to a base reference when creating the new Base by passing
it a Derived reference, and accept it. Base's copy constructor will accept a
derived reference based on Derived being derived from Base and therefore
holding a Base within itself. This is no different from your Clone()
polymorphism as you call it, but without the 'polymorphism' <g> .

The Clone method itself acts as the Factory Method to ensure the
correct type of derived object is created.


The problem is implementing the Clone() method. You have to repeat all the
initializations of your base class, which might be voluminous. In copy
constructors, you just pass your object down to the base class and each base
class initializes its own variables. There is no repeat initializations.

As a matter of fact, if a base class in a framework using Clone() has
private variables which need to be initialized, and since private variables
are completely inaccessible to the derived class, I don't even understand
how Clone() can even work at all, since it is impossible for the derived
class to properly initialize the base class's private variables. With copy
construction this problem does not exist.

I consider Clone() an essentially broken idea except for very independent
objects, but even there copy constructors are superior. They are easier to
code and use and are more robust.

But maybe I have missed something. If so, please enlighten me.

Eddie
Jul 21 '05 #12

P: n/a
Edward,
But maybe I have missed something. If so, please enlighten me. Unfortunately I know my limitations! ;-)

(sincerely not meant as a slam against you or anyone!).
Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast from a
derived reference to a base reference when creating the new Base by passing it a Derived reference, and accept it. Base's copy constructor will accept a derived reference based on Derived being derived from Base and therefore
holding a Base within itself. This is no different from your Clone()
polymorphism as you call it, but without the 'polymorphism' <g> . Huh? "new Base(d)" gives you a Base object not a Derived object, or is there
some new obscure rule going on here to enable C++ code to be even more
confusing?

The point of my suggesting using polymorphism is to get a Derived object out
if you have a Derived object in. As far as I can tell the above paragraph
says, Create a new Base object, that holds a reference to a Derived object
(which is composition, not copying!).

I really don't have any thing further to add to my original comments, you
are welcome to my original comments for what they are worth. I hope you
understand if I drop out of this discussion.

Hope this helps
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl... Jay B. Harlow [MVP - Outlook] wrote:
Edward,
OTOH copy constructors have no such problems and are actually
polymorphic by nature. If my base class has a copy constructor, I
simply call the base class copy constructor passing the other object
that needs to be copied to the base class, then I copy any other
non-base fields from the copied object to my own. This is much
easier and more natural than implementing Clone() in a class
hierarchy.
Can you give a C++ example seem to be missing something in your
explanation. It may be my just being away from C++ too long. ;-)


In standard C++:

class Base
{
public:
int i;
Base() { i = 0; }
Base(const Base & b) { i = b.i; }
};

class Derived : public Base
{
public:
double db;
Derived() { db = 1.0; }
Derived(const Derived & d) : Base(d) { db = d.db; }
};

Derived dfirst; // Default constructor
Derived dsecond(dfirst); // Copy constructor

When you invoke Derived's copy constructor, it passes the reference to
Base's copy constructor. Since a Derived contains a Base, there is no
problem for Base initializing its own variable(s) from that copy. The
compiler automatically downcasts from a Derived reference to a Base
reference when passing copy constructors down the chain.

With a copy constructor: If I have an object that is actually type
Derived in a Base variable, to create a copy of Derived I would need
to call new Derived(oldBase). correct?


No, see above.

// Given:
// Consider that new Derived may have come from a factory method
Base oldBase = new Derived();


In C++ this is:

Base * oldBase = new Derived();

// elsewhere where we don't know what the concrete type of oldBase is:
// What do you put for the new type in the following statement?
// considering that I want the exact same type back?
Base copyBase = new ????(oldBase);


If you do:

Base * copyBase = new Derived(*oldBase);

you get a compiler error since you are passing a reference to a base and

the Derived's copy constructor expects a reference to a Derived. If you do:

Base * copyBase = new Derived(dynamic_cast<Derived &>(*oldBase));

you are fine as long as oldBase is really pointing to a derived object. If
it is not, that is your fault and you will get a bad_cast exception thrown. The Derived class's copy constructor above expects a Derived object. Of
course you can add another copy constructor to Derived that takes a 'const
Base &' like this:

Derived(const Base & b) : Base(b) { db = 1.0; }

and now you are successful doing:

Base * copyBase = new Derived(*oldBase);

and then you can pass Base or Derived references to it. In this sense C++
copy constructors are not polymorphic, and I shouldn't have said that. It
was bad wording and the word polymorphic was wrong. C++ constructors are not virtual and work on the static type, not the dynamic type. What I meant to
say is that derived class objects can be passed down to base class copy
constructors through automatic downcasting. I consider this much better in
this particular case than polymorphism.

With the Clone pattern I can simply call the Clone method, having
defined Clone method as virtual in Base & Derived.

Base copyBase = oldBase.Clone();
// copyBase will still be a Derived object.
You can create a base object from a derived copy also.

Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast from a
derived reference to a base reference when creating the new Base by

passing it a Derived reference, and accept it. Base's copy constructor will accept a derived reference based on Derived being derived from Base and therefore
holding a Base within itself. This is no different from your Clone()
polymorphism as you call it, but without the 'polymorphism' <g> .

The Clone method itself acts as the Factory Method to ensure the
correct type of derived object is created.
The problem is implementing the Clone() method. You have to repeat all the
initializations of your base class, which might be voluminous. In copy
constructors, you just pass your object down to the base class and each

base class initializes its own variables. There is no repeat initializations.

As a matter of fact, if a base class in a framework using Clone() has
private variables which need to be initialized, and since private variables are completely inaccessible to the derived class, I don't even understand
how Clone() can even work at all, since it is impossible for the derived
class to properly initialize the base class's private variables. With copy
construction this problem does not exist.

I consider Clone() an essentially broken idea except for very independent
objects, but even there copy constructors are superior. They are easier to
code and use and are more robust.

But maybe I have missed something. If so, please enlighten me.

Eddie

Jul 21 '05 #13

P: n/a

The problem is implementing the Clone() method.
You have to repeat all the
initializations of your base class, which might be voluminous.
.......
I don't even understand
how Clone() can even work at all,
since it is impossible for the derived
class to properly initialize the base
class's private variables


Good point. I never thought of it it this way. I guess it's becoming clearer
to me why copy constructors can be a great idea sometimes.

As for your origional wondering why the FCL doesn't employ copy constructors
more often... maybe the people in charge of design didn't have your
foresight ;)

Thanks for your thoughts on this... I've found it interesting and maybe will
try to use copy constructors more often.

Trev.
Jul 21 '05 #14

P: n/a
Jay B. Harlow [MVP - Outlook] wrote:
Edward,
But maybe I have missed something. If so, please enlighten me. Unfortunately I know my limitations! ;-)

(sincerely not meant as a slam against you or anyone!).
Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast
from a derived reference to a base reference when creating the new
Base by passing it a Derived reference, and accept it. Base's copy
constructor will accept a derived reference based on Derived being
derived from Base and therefore holding a Base within itself. This
is no different from your Clone() polymorphism as you call it, but
without the 'polymorphism' <g> .

Huh? "new Base(d)" gives you a Base object not a Derived object, or
is there some new obscure rule going on here to enable C++ code to be
even more confusing?


Where do I say that "new Base(d)" gives one a Derived * object ? Clearly
above it gives one Base * object which one assigns to the Base * b variable.

The point of my suggesting using polymorphism is to get a Derived
object out if you have a Derived object in. As far as I can tell the
above paragraph says, Create a new Base object, that holds a
reference to a Derived object (which is composition, not copying!).
No, it accepts a reference to a Derived object passed to it in its
"Base(const Base &)" constructor. The compiler automatically downcasts the
"const Derived &" that is passed to it as a "const Base &". That is a copy
constructor. It doesn't mean that base "holds a reference to a Derived
object". It simply means it uses the Base portion of the Derived reference
passed to it to initialize its own variables by copying the Base values
passed in to it.

I really don't have any thing further to add to my original comments,
you are welcome to my original comments for what they are worth. I
hope you understand if I drop out of this discussion.
No problem. I wasn't trying to initimidate anyone or be egotistical, just
attempting to clarify the use of Clone() over copy constructors in the .NET
framework classes. As I said, for me coming from largely the C++ world, copy
constructors are definitely better. They are easier to write and ensure that
an object is constructed based on another copy of the same type of object,
and they work throughout a base/derived framework. The Clone() method looks
nice but, as I have discovered, is difficult to implement and has holes when
it comes to cloning base class fields when those fields are private. The one
upside to Clone() and ICloneable is that one can test an object at run-time
to see if it is cloneable. This doesn't make up for me the downside of
Clone() which I have already mentioned.

Hope this helps
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Jay B. Harlow [MVP - Outlook] wrote:
Edward,
OTOH copy constructors have no such problems and are actually
polymorphic by nature. If my base class has a copy constructor, I
simply call the base class copy constructor passing the other
object that needs to be copied to the base class, then I copy any
other non-base fields from the copied object to my own. This is
much easier and more natural than implementing Clone() in a class
hierarchy.

Can you give a C++ example seem to be missing something in your
explanation. It may be my just being away from C++ too long. ;-)


In standard C++:

class Base
{
public:
int i;
Base() { i = 0; }
Base(const Base & b) { i = b.i; }
};

class Derived : public Base
{
public:
double db;
Derived() { db = 1.0; }
Derived(const Derived & d) : Base(d) { db = d.db; }
};

Derived dfirst; // Default constructor
Derived dsecond(dfirst); // Copy constructor

When you invoke Derived's copy constructor, it passes the reference
to Base's copy constructor. Since a Derived contains a Base, there
is no problem for Base initializing its own variable(s) from that
copy. The compiler automatically downcasts from a Derived reference
to a Base reference when passing copy constructors down the chain.

With a copy constructor: If I have an object that is actually type
Derived in a Base variable, to create a copy of Derived I would need
to call new Derived(oldBase). correct?


No, see above.

// Given:
// Consider that new Derived may have come from a factory method
Base oldBase = new Derived();


In C++ this is:

Base * oldBase = new Derived();

// elsewhere where we don't know what the concrete type of oldBase
is: // What do you put for the new type in the following statement?
// considering that I want the exact same type back?
Base copyBase = new ????(oldBase);


If you do:

Base * copyBase = new Derived(*oldBase);

you get a compiler error since you are passing a reference to a base
and the Derived's copy constructor expects a reference to a Derived.
If you do:

Base * copyBase = new Derived(dynamic_cast<Derived &>(*oldBase));

you are fine as long as oldBase is really pointing to a derived
object. If it is not, that is your fault and you will get a bad_cast
exception thrown. The Derived class's copy constructor above expects
a Derived object. Of course you can add another copy constructor to
Derived that takes a 'const Base &' like this:

Derived(const Base & b) : Base(b) { db = 1.0; }

and now you are successful doing:

Base * copyBase = new Derived(*oldBase);

and then you can pass Base or Derived references to it. In this
sense C++ copy constructors are not polymorphic, and I shouldn't
have said that. It was bad wording and the word polymorphic was
wrong. C++ constructors are not virtual and work on the static type,
not the dynamic type. What I meant to say is that derived class
objects can be passed down to base class copy constructors through
automatic downcasting. I consider this much better in this
particular case than polymorphism.

With the Clone pattern I can simply call the Clone method, having
defined Clone method as virtual in Base & Derived.

Base copyBase = oldBase.Clone();
// copyBase will still be a Derived object.


You can create a base object from a derived copy also.

Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast
from a derived reference to a base reference when creating the new
Base by passing it a Derived reference, and accept it. Base's copy
constructor will accept a derived reference based on Derived being
derived from Base and therefore holding a Base within itself. This
is no different from your Clone() polymorphism as you call it, but
without the 'polymorphism' <g> .

The Clone method itself acts as the Factory Method to ensure the
correct type of derived object is created.


The problem is implementing the Clone() method. You have to repeat
all the initializations of your base class, which might be
voluminous. In copy constructors, you just pass your object down to
the base class and each base class initializes its own variables.
There is no repeat initializations.

As a matter of fact, if a base class in a framework using Clone() has
private variables which need to be initialized, and since private
variables are completely inaccessible to the derived class, I don't
even understand how Clone() can even work at all, since it is
impossible for the derived class to properly initialize the base
class's private variables. With copy construction this problem does
not exist.

I consider Clone() an essentially broken idea except for very
independent objects, but even there copy constructors are superior.
They are easier to code and use and are more robust.

But maybe I have missed something. If so, please enlighten me.

Eddie

Jul 21 '05 #15

P: n/a
Codemonkey wrote:
The problem is implementing the Clone() method.
You have to repeat all the
initializations of your base class, which might be voluminous.
......
I don't even understand
how Clone() can even work at all,
since it is impossible for the derived
class to properly initialize the base
class's private variables


Good point. I never thought of it it this way. I guess it's becoming
clearer to me why copy constructors can be a great idea sometimes.

As for your origional wondering why the FCL doesn't employ copy
constructors more often... maybe the people in charge of design
didn't have your foresight ;)


Thanks for the compliment as it is appreciated. MS has done C++ very well,
especially under Stan Lippman, so maybe they should have spoken to their own
C++ development team to discover why copy constructors are better than
Clone() in the FCL.

As for my foresight, I wish employers would recognize it and hire me for a
job where I could make a living. That would lessen the pain of using Clone()
instead of copy constructors for current FCL classes <g> .

Thanks for your thoughts on this... I've found it interesting and
maybe will try to use copy constructors more often.


Good luck !
Jul 21 '05 #16

P: n/a
Edward,
The Clone() method looks
nice but, as I have discovered, is difficult to implement and has holes when it comes to cloning base class fields when those fields are private. Which is why I implemented Clone in the terms of a copy constructor ;-)

Coming from C++ Clone is definitely different, however I don't find it
difficult per se.

Something like (VB.NET)

Public Class Base
Implements ICloneable

Private Readonly m_name As String

Public Sub New(ByVal name As string)
m_name = name
End

Protected Sub New(ByVal other As Base)
m_name = other.m_name
End Sub

Public Overridable Function Clone() As Object Implements
ICloneable.Clone
Return New Base(Me)
End Sub

End Class

Public Class Derived
Inherits Base

Private Readonly m_stuff As Integer

Public Sub New(ByVal name As String, ByVal stuff As Integer)
MyBase.New(name)
m_stuff = stuff
End Sub

Protected Sub New(ByVal other As Derived)
Mybase.New(other)
m_stuff = other.m_stuff
End Sub

Public Overrides Function Clone() As Object
Return New Derived(Me)
End Sub

End Class

Public Module TestModule

Public Sub Main()
Dim b1 As New Base("jay")
Dim b2 As New Derived("Edward", 1)
ProcessClone(b1)
ProcessClone(b2)
End Sub

Public Sub ProcessClone(ByVal b As Base)
Dim newBase As Base = DirectCast(b.Clone(), Base)
Debug.WriteLine(b Is newBase, "b Is newBase")
Debug.WriteLine(b.GetType(), "b type")
Debug.WriteLine(newBase.GetType(), "newBase type")
End Sub

End Module

The copy constructor is an implementation detail, hence its protected.

If you want a C# or C++ version I can see what I can do.

Hope this helps
Jay
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:eF**************@tk2msftngp13.phx.gbl... Jay B. Harlow [MVP - Outlook] wrote:
Edward,
But maybe I have missed something. If so, please enlighten me. Unfortunately I know my limitations! ;-)

(sincerely not meant as a slam against you or anyone!).
Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast
from a derived reference to a base reference when creating the new
Base by passing it a Derived reference, and accept it. Base's copy
constructor will accept a derived reference based on Derived being
derived from Base and therefore holding a Base within itself. This
is no different from your Clone() polymorphism as you call it, but
without the 'polymorphism' <g> .

Huh? "new Base(d)" gives you a Base object not a Derived object, or
is there some new obscure rule going on here to enable C++ code to be
even more confusing?


Where do I say that "new Base(d)" gives one a Derived * object ? Clearly
above it gives one Base * object which one assigns to the Base * b

variable.

The point of my suggesting using polymorphism is to get a Derived
object out if you have a Derived object in. As far as I can tell the
above paragraph says, Create a new Base object, that holds a
reference to a Derived object (which is composition, not copying!).
No, it accepts a reference to a Derived object passed to it in its
"Base(const Base &)" constructor. The compiler automatically downcasts the
"const Derived &" that is passed to it as a "const Base &". That is a copy
constructor. It doesn't mean that base "holds a reference to a Derived
object". It simply means it uses the Base portion of the Derived reference
passed to it to initialize its own variables by copying the Base values
passed in to it.

I really don't have any thing further to add to my original comments,
you are welcome to my original comments for what they are worth. I
hope you understand if I drop out of this discussion.


No problem. I wasn't trying to initimidate anyone or be egotistical, just
attempting to clarify the use of Clone() over copy constructors in the

..NET framework classes. As I said, for me coming from largely the C++ world, copy constructors are definitely better. They are easier to write and ensure that an object is constructed based on another copy of the same type of object,
and they work throughout a base/derived framework. The Clone() method looks nice but, as I have discovered, is difficult to implement and has holes when it comes to cloning base class fields when those fields are private. The one upside to Clone() and ICloneable is that one can test an object at run-time to see if it is cloneable. This doesn't make up for me the downside of
Clone() which I have already mentioned.

Hope this helps
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Jay B. Harlow [MVP - Outlook] wrote:
Edward,
> OTOH copy constructors have no such problems and are actually
> polymorphic by nature. If my base class has a copy constructor, I
> simply call the base class copy constructor passing the other
> object that needs to be copied to the base class, then I copy any
> other non-base fields from the copied object to my own. This is
> much easier and more natural than implementing Clone() in a class
> hierarchy.

Can you give a C++ example seem to be missing something in your
explanation. It may be my just being away from C++ too long. ;-)

In standard C++:

class Base
{
public:
int i;
Base() { i = 0; }
Base(const Base & b) { i = b.i; }
};

class Derived : public Base
{
public:
double db;
Derived() { db = 1.0; }
Derived(const Derived & d) : Base(d) { db = d.db; }
};

Derived dfirst; // Default constructor
Derived dsecond(dfirst); // Copy constructor

When you invoke Derived's copy constructor, it passes the reference
to Base's copy constructor. Since a Derived contains a Base, there
is no problem for Base initializing its own variable(s) from that
copy. The compiler automatically downcasts from a Derived reference
to a Base reference when passing copy constructors down the chain.
With a copy constructor: If I have an object that is actually type
Derived in a Base variable, to create a copy of Derived I would need
to call new Derived(oldBase). correct?

No, see above.
// Given:
// Consider that new Derived may have come from a factory method
Base oldBase = new Derived();

In C++ this is:

Base * oldBase = new Derived();
// elsewhere where we don't know what the concrete type of oldBase
is: // What do you put for the new type in the following statement?
// considering that I want the exact same type back?
Base copyBase = new ????(oldBase);

If you do:

Base * copyBase = new Derived(*oldBase);

you get a compiler error since you are passing a reference to a base
and the Derived's copy constructor expects a reference to a Derived.
If you do:

Base * copyBase = new Derived(dynamic_cast<Derived &>(*oldBase));

you are fine as long as oldBase is really pointing to a derived
object. If it is not, that is your fault and you will get a bad_cast
exception thrown. The Derived class's copy constructor above expects
a Derived object. Of course you can add another copy constructor to
Derived that takes a 'const Base &' like this:

Derived(const Base & b) : Base(b) { db = 1.0; }

and now you are successful doing:

Base * copyBase = new Derived(*oldBase);

and then you can pass Base or Derived references to it. In this
sense C++ copy constructors are not polymorphic, and I shouldn't
have said that. It was bad wording and the word polymorphic was
wrong. C++ constructors are not virtual and work on the static type,
not the dynamic type. What I meant to say is that derived class
objects can be passed down to base class copy constructors through
automatic downcasting. I consider this much better in this
particular case than polymorphism.
With the Clone pattern I can simply call the Clone method, having
defined Clone method as virtual in Base & Derived.

Base copyBase = oldBase.Clone();
// copyBase will still be a Derived object.

You can create a base object from a derived copy also.

Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast
from a derived reference to a base reference when creating the new
Base by passing it a Derived reference, and accept it. Base's copy
constructor will accept a derived reference based on Derived being
derived from Base and therefore holding a Base within itself. This
is no different from your Clone() polymorphism as you call it, but
without the 'polymorphism' <g> .
The Clone method itself acts as the Factory Method to ensure the
correct type of derived object is created.

The problem is implementing the Clone() method. You have to repeat
all the initializations of your base class, which might be
voluminous. In copy constructors, you just pass your object down to
the base class and each base class initializes its own variables.
There is no repeat initializations.

As a matter of fact, if a base class in a framework using Clone() has
private variables which need to be initialized, and since private
variables are completely inaccessible to the derived class, I don't
even understand how Clone() can even work at all, since it is
impossible for the derived class to properly initialize the base
class's private variables. With copy construction this problem does
not exist.

I consider Clone() an essentially broken idea except for very
independent objects, but even there copy constructors are superior.
They are easier to code and use and are more robust.

But maybe I have missed something. If so, please enlighten me.

Eddie


Jul 21 '05 #17

P: n/a
Jay B. Harlow [MVP - Outlook] wrote:
Edward,
The Clone() method looks
nice but, as I have discovered, is difficult to implement and has
holes when it comes to cloning base class fields when those fields
are private. Which is why I implemented Clone in the terms of a copy constructor
;-)

Coming from C++ Clone is definitely different, however I don't find it
difficult per se.

Something like (VB.NET)

Public Class Base
Implements ICloneable

Private Readonly m_name As String

Public Sub New(ByVal name As string)
m_name = name
End

Protected Sub New(ByVal other As Base)
m_name = other.m_name
End Sub

Public Overridable Function Clone() As Object Implements
ICloneable.Clone
Return New Base(Me)
End Sub

End Class

Public Class Derived
Inherits Base

Private Readonly m_stuff As Integer

Public Sub New(ByVal name As String, ByVal stuff As Integer)
MyBase.New(name)
m_stuff = stuff
End Sub

Protected Sub New(ByVal other As Derived)
Mybase.New(other)
m_stuff = other.m_stuff
End Sub

Public Overrides Function Clone() As Object
Return New Derived(Me)
End Sub

End Class

Public Module TestModule

Public Sub Main()
Dim b1 As New Base("jay")
Dim b2 As New Derived("Edward", 1)
ProcessClone(b1)
ProcessClone(b2)
End Sub

Public Sub ProcessClone(ByVal b As Base)
Dim newBase As Base = DirectCast(b.Clone(), Base)
Debug.WriteLine(b Is newBase, "b Is newBase")
Debug.WriteLine(b.GetType(), "b type")
Debug.WriteLine(newBase.GetType(), "newBase type")
End Sub

End Module

The copy constructor is an implementation detail, hence its protected.

If you want a C# or C++ version I can see what I can do.


I am fine with the VB since it is easy to understand. I understand what you
are doing by using the copy constructor to implement Clone(). I find this
works well and I appreciate the technique. Thanks ! I still prefer a public
copy constructor, because the syntax of creating a new object using a public
copy constructor is more natural for me, but implementing Clone() in turns
of a protected copy constructor is just as good and gives you the advantage
of tagging your class as cloneable.

Hope this helps
Jay
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:eF**************@tk2msftngp13.phx.gbl...
Jay B. Harlow [MVP - Outlook] wrote:
Edward,
But maybe I have missed something. If so, please enlighten me.
Unfortunately I know my limitations! ;-)

(sincerely not meant as a slam against you or anyone!).

Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast
from a derived reference to a base reference when creating the new
Base by passing it a Derived reference, and accept it. Base's copy
constructor will accept a derived reference based on Derived being
derived from Base and therefore holding a Base within itself. This
is no different from your Clone() polymorphism as you call it, but
without the 'polymorphism' <g> .
Huh? "new Base(d)" gives you a Base object not a Derived object, or
is there some new obscure rule going on here to enable C++ code to
be even more confusing?


Where do I say that "new Base(d)" gives one a Derived * object ?
Clearly above it gives one Base * object which one assigns to the
Base * b variable.

The point of my suggesting using polymorphism is to get a Derived
object out if you have a Derived object in. As far as I can tell the
above paragraph says, Create a new Base object, that holds a
reference to a Derived object (which is composition, not copying!).


No, it accepts a reference to a Derived object passed to it in its
"Base(const Base &)" constructor. The compiler automatically
downcasts the "const Derived &" that is passed to it as a "const
Base &". That is a copy constructor. It doesn't mean that base
"holds a reference to a Derived object". It simply means it uses the
Base portion of the Derived reference passed to it to initialize its
own variables by copying the Base values passed in to it.

I really don't have any thing further to add to my original
comments, you are welcome to my original comments for what they are
worth. I hope you understand if I drop out of this discussion.


No problem. I wasn't trying to initimidate anyone or be egotistical,
just attempting to clarify the use of Clone() over copy constructors
in the .NET framework classes. As I said, for me coming from largely
the C++ world, copy constructors are definitely better. They are
easier to write and ensure that an object is constructed based on
another copy of the same type of object, and they work throughout a
base/derived framework. The Clone() method looks nice but, as I have
discovered, is difficult to implement and has holes when it comes to
cloning base class fields when those fields are private. The one
upside to Clone() and ICloneable is that one can test an object at
run-time to see if it is cloneable. This doesn't make up for me the
downside of Clone() which I have already mentioned.

Hope this helps
Jay

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Jay B. Harlow [MVP - Outlook] wrote:
> Edward,
>> OTOH copy constructors have no such problems and are actually
>> polymorphic by nature. If my base class has a copy constructor, I
>> simply call the base class copy constructor passing the other
>> object that needs to be copied to the base class, then I copy any
>> other non-base fields from the copied object to my own. This is
>> much easier and more natural than implementing Clone() in a class
>> hierarchy.
>
> Can you give a C++ example seem to be missing something in your
> explanation. It may be my just being away from C++ too long. ;-)

In standard C++:

class Base
{
public:
int i;
Base() { i = 0; }
Base(const Base & b) { i = b.i; }
};

class Derived : public Base
{
public:
double db;
Derived() { db = 1.0; }
Derived(const Derived & d) : Base(d) { db = d.db; }
};

Derived dfirst; // Default constructor
Derived dsecond(dfirst); // Copy constructor

When you invoke Derived's copy constructor, it passes the reference
to Base's copy constructor. Since a Derived contains a Base, there
is no problem for Base initializing its own variable(s) from that
copy. The compiler automatically downcasts from a Derived reference
to a Base reference when passing copy constructors down the chain.

>
> With a copy constructor: If I have an object that is actually type
> Derived in a Base variable, to create a copy of Derived I would
> need to call new Derived(oldBase). correct?

No, see above.

>
> // Given:
> // Consider that new Derived may have come from a factory method
> Base oldBase = new Derived();

In C++ this is:

Base * oldBase = new Derived();

>
> // elsewhere where we don't know what the concrete type of oldBase
> is: // What do you put for the new type in the following
> statement? // considering that I want the exact same type back?
> Base copyBase = new ????(oldBase);

If you do:

Base * copyBase = new Derived(*oldBase);

you get a compiler error since you are passing a reference to a
base and the Derived's copy constructor expects a reference to a
Derived. If you do:

Base * copyBase = new Derived(dynamic_cast<Derived &>(*oldBase));

you are fine as long as oldBase is really pointing to a derived
object. If it is not, that is your fault and you will get a
bad_cast exception thrown. The Derived class's copy constructor
above expects a Derived object. Of course you can add another copy
constructor to Derived that takes a 'const Base &' like this:

Derived(const Base & b) : Base(b) { db = 1.0; }

and now you are successful doing:

Base * copyBase = new Derived(*oldBase);

and then you can pass Base or Derived references to it. In this
sense C++ copy constructors are not polymorphic, and I shouldn't
have said that. It was bad wording and the word polymorphic was
wrong. C++ constructors are not virtual and work on the static
type, not the dynamic type. What I meant to say is that derived
class objects can be passed down to base class copy constructors
through automatic downcasting. I consider this much better in this
particular case than polymorphism.

>
> With the Clone pattern I can simply call the Clone method, having
> defined Clone method as virtual in Base & Derived.
>
> Base copyBase = oldBase.Clone();
> // copyBase will still be a Derived object.

You can create a base object from a derived copy also.

Derived d;
Base * b(new Base(d));

is perfectly fine in C++. The compiler will automatically downcast
from a derived reference to a base reference when creating the new
Base by passing it a Derived reference, and accept it. Base's copy
constructor will accept a derived reference based on Derived being
derived from Base and therefore holding a Base within itself. This
is no different from your Clone() polymorphism as you call it, but
without the 'polymorphism' <g> .

>
> The Clone method itself acts as the Factory Method to ensure the
> correct type of derived object is created.

The problem is implementing the Clone() method. You have to repeat
all the initializations of your base class, which might be
voluminous. In copy constructors, you just pass your object down to
the base class and each base class initializes its own variables.
There is no repeat initializations.

As a matter of fact, if a base class in a framework using Clone()
has private variables which need to be initialized, and since
private variables are completely inaccessible to the derived
class, I don't even understand how Clone() can even work at all,
since it is impossible for the derived class to properly
initialize the base class's private variables. With copy
construction this problem does not exist.

I consider Clone() an essentially broken idea except for very
independent objects, but even there copy constructors are superior.
They are easier to code and use and are more robust.

But maybe I have missed something. If so, please enlighten me.

Eddie

Jul 21 '05 #18

P: n/a

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Codemonkey wrote:
The problem is implementing the Clone() method.
You have to repeat all the
initializations of your base class, which might be voluminous.
......
I don't even understand
how Clone() can even work at all,
since it is impossible for the derived
class to properly initialize the base
class's private variables


Good point. I never thought of it it this way. I guess it's becoming
clearer to me why copy constructors can be a great idea sometimes.

As for your origional wondering why the FCL doesn't employ copy
constructors more often... maybe the people in charge of design
didn't have your foresight ;)


Thanks for the compliment as it is appreciated. MS has done C++ very well,
especially under Stan Lippman, so maybe they should have spoken to their

own C++ development team to discover why copy constructors are better than
Clone() in the FCL.
From what I've read I'd argue that copy constructors are not better, but a
more risky construct. Considering the Composition arguments combined with
not being able to copy an object safely as its concrete type(and downcast to
the variable type) without knowing the type ahead of time, or that without
documentation you cannot know for sure that you are calling a copy
constructor, not just a badly typed constructor, or an ambigious constructor
call using some of the more complicated language rules that not everyone is
familiar with, I'd call Copy Constructors a technique that lacks a good deal
of grace.
Calling Clone tells me I have a copy of an object, new
myObject(myObjectReference) 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). It also guarentees
that I won't lose any data that makes sense to copy. A copy constructor very
well could ignore many fields which shouldn't be dumped, simply because you
called a base constructor instead of the concrete type constructor. I don't
consider a copy without copying ALL relevent data a copy, but more of a near
type conversion. It also doesn't help as far as interfaces go, how exactly
do you clone an object that implements, say, IMyDataObject with a copy
constructor? What constructor do you call?
Is there an argument for why copy constructors are better, other than simply
because they are easier(for you) to type? The ease of constructors calling
eachother doesn't hold up, you can use protected constructors or a protected
virtual method to do the same thing: protected virtual Clone(BaseType
sourceObj, BaseType newObj); in a polymorphic fashion(although it'd require
some casting and type checking), depending on your needs. And I personally
find that calling new to create a copy is not anywhere near as clear, from a
maintainablitiy and readability standpoint as .Clone() is. The only argument
I've seen for copy constructors is that its easier for C++ developers to
use, and an unsubstantiated "its better".
Please, explain why its better, not simply by basing it on C++, but on
technical, .NET reasons its better. This is not an entirely C++ world, and
some pieces of C++ are probably better lost.

As for my foresight, I wish employers would recognize it and hire me for a
job where I could make a living. That would lessen the pain of using Clone() instead of copy constructors for current FCL classes <g> .

Thanks for your thoughts on this... I've found it interesting and
maybe will try to use copy constructors more often.


Good luck !

Jul 21 '05 #19

P: n/a
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
Codemonkey wrote:
The problem is implementing the Clone() method.
You have to repeat all the
initializations of your base class, which might be voluminous.

......

I don't even understand
how Clone() can even work at all,
since it is impossible for the derived
class to properly initialize the base
class's private variables

Good point. I never thought of it it this way. I guess it's becoming
clearer to me why copy constructors can be a great idea sometimes.

As for your origional wondering why the FCL doesn't employ copy
constructors more often... maybe the people in charge of design
didn't have your foresight ;)
Thanks for the compliment as it is appreciated. MS has done C++ very
well, especially under Stan Lippman, so maybe they should have
spoken to their own C++ development team to discover why copy
constructors are better than Clone() in the FCL.


From what I've read I'd argue that copy constructors are not better,
but a more risky construct.


What that you have read about them that leads you to believe this ? Please
give technical arguments.
Considering the Composition arguments
combined with not being able to copy an object safely as its concrete
type(and downcast to the variable type) without knowing the type
ahead of time
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.
, or that without documentation you cannot know for sure
that you are calling a copy constructor, not just a badly typed
constructor, or an ambigious constructor call using some of the more
complicated language rules that not everyone is familiar with
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.
, I'd
call Copy Constructors a technique that lacks a good deal of grace.
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.
Calling Clone tells me I have a copy of an object, new
myObject(myObjectReference) 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).
"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)."
It
also guarentees that I won't lose any data that makes sense to copy.
A copy constructor very well could ignore many fields which shouldn't
be dumped, simply because you called a base constructor instead of
the concrete type constructor. I don't consider a copy without
copying ALL relevent data a copy, but more of a near type conversion.
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.
It also doesn't help as far as interfaces go, how exactly do you
clone an object that implements, say, IMyDataObject with a copy
constructor?
Interfaces are member function contracts and do not contain data AFAIK.
What constructor do you call?
See above.
Is there an argument for why copy constructors are better, other than
simply because they are easier(for you) to type? The ease of
constructors calling eachother doesn't hold up
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.
, you can use protected
constructors or a protected virtual method to do the same thing:
protected virtual Clone(BaseType sourceObj, BaseType newObj); in a
polymorphic fashion(although it'd require some casting and type
checking), depending on your needs.
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.
And I personally find that
calling new to create a copy is not anywhere near as clear, from a
maintainablitiy and readability standpoint as .Clone() is.
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().
The only
argument I've seen for copy constructors is that its easier for C++
developers to use, and an unsubstantiated "its better".
Please, explain why its better, not simply by basing it on C++, but on
technical, .NET reasons its better. This is not an entirely C++
world, and some pieces of C++ are probably better lost.
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.

As for my foresight, I wish employers would recognize it and hire me
for a job where I could make a living. That would lessen the pain of
using Clone() instead of copy constructors for current FCL classes
<g> .

Thanks for your thoughts on this... I've found it interesting and
maybe will try to use copy constructors more often.


Good luck !

Jul 21 '05 #20

P: n/a
> > From what I've read I'd argue that copy constructors are not better,
but a more risky construct.
What that you have read about them that leads you to believe this ? Please
give technical arguments.
Considering the Composition arguments
combined with not being able to copy an object safely as its concrete
type(and downcast to the variable type) without knowing the type
ahead of time


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(der ivedObj);
//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(der ivedObj);
//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.
, or that without documentation you cannot know for sure
that you are calling a copy constructor, not just a badly typed
constructor, or an ambigious constructor call using some of the more
complicated language rules that not everyone is familiar with


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.
, I'd
call Copy Constructors a technique that lacks a good deal of grace.
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.
Calling Clone tells me I have a copy of an object, new
myObject(myObjectReference) 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).
"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.
It
also guarentees that I won't lose any data that makes sense to copy.
A copy constructor very well could ignore many fields which shouldn't
be dumped, simply because you called a base constructor instead of
the concrete type constructor. I don't consider a copy without
copying ALL relevent data a copy, but more of a near type conversion.


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?

It also doesn't help as far as interfaces go, how exactly do you
clone an object that implements, say, IMyDataObject with a copy
constructor?


Interfaces are member function contracts and do not contain data AFAIK.
What constructor do you call?


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).
Is there an argument for why copy constructors are better, other than
simply because they are easier(for you) to type? The ease of
constructors calling eachother doesn't hold up


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)
}
, you can use protected
constructors or a protected virtual method to do the same thing:
protected virtual Clone(BaseType sourceObj, BaseType newObj); in a
polymorphic fashion(although it'd require some casting and type
checking), depending on your needs.


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.
And I personally find that
calling new to create a copy is not anywhere near as clear, from a
maintainablitiy and readability standpoint as .Clone() is.


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.
The only
argument I've seen for copy constructors is that its easier for C++
developers to use, and an unsubstantiated "its better".
Please, explain why its better, not simply by basing it on C++, but on
technical, .NET reasons its better. This is not an entirely C++
world, and some pieces of C++ are probably better lost.
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?
Jul 21 '05 #21

P: n/a
Daniel O'Connell wrote:
From what I've read I'd argue that copy constructors are not better,
but a more risky construct.
What that you have read about them that leads you to believe this ?
Please give technical arguments.
Considering the Composition arguments
combined with not being able to copy an object safely as its
concrete type(and downcast to the variable type) without knowing
the type ahead of time


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(der ivedObj); //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(der ivedObj);
//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.
, or that without documentation you cannot know for sure
that you are calling a copy constructor, not just a badly typed
constructor, or an ambigious constructor call using some of the more
complicated language rules that not everyone is familiar with
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.


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.
, I'd
call Copy Constructors a technique that lacks a good deal of grace.


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.
Calling Clone tells me I have a copy of an object, new
myObject(myObjectReference) 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).


"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.


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.
It
also guarentees that I won't lose any data that makes sense to copy.
A copy constructor very well could ignore many fields which
shouldn't be dumped, simply because you called a base constructor
instead of the concrete type constructor. I don't consider a copy
without copying ALL relevent data a copy, but more of a near type
conversion.


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?


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.

It also doesn't help as far as interfaces go, how exactly do you
clone an object that implements, say, IMyDataObject with a copy
constructor?
Interfaces are member function contracts and do not contain data
AFAIK.
What constructor do you call?


See above.

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.
Is there an argument for why copy constructors are better, other
than simply because they are easier(for you) to type? The ease of
constructors calling eachother doesn't hold up
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);
}


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.
Jul 21 '05 #22

P: n/a

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:uF****************@TK2MSFTNGP12.phx.gbl...
Daniel O'Connell wrote:
From what I've read I'd argue that copy constructors are not better,
but a more risky construct.

What that you have read about them that leads you to believe this ?
Please give technical arguments.

Considering the Composition arguments
combined with not being able to copy an object safely as its
concrete type(and downcast to the variable type) without knowing
the type ahead of time

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(der ivedObj); //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(der ivedObj);
//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. 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.
, or that without documentation you cannot know for sure
that you are calling a copy constructor, not just a badly typed
constructor, or an ambigious constructor call using some of the more
complicated language rules that not everyone is familiar with

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.


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.

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'd
call Copy Constructors a technique that lacks a good deal of grace.

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.

Calling Clone tells me I have a copy of an object, new
myObject(myObjectReference) 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).

"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.


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.
It
also guarentees that I won't lose any data that makes sense to copy.
A copy constructor very well could ignore many fields which
shouldn't be dumped, simply because you called a base constructor
instead of the concrete type constructor. I don't consider a copy
without coying ALL relevent data a copy, but more of a near type
conversion.

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?


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.

It also doesn't help as far as interfaces go, how exactly do you
clone an object that implements, say, IMyDataObject with a copy
constructor?

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

What constructor do you call?

See above.
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.


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).
Is there an argument for why copy constructors are better, other
than simply because they are easier(for you) to type? The ease of
constructors calling eachother doesn't hold up

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);
}


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.
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, ;)

Jul 21 '05 #23

P: n/a
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...5/copying.html
Jul 21 '05 #24

P: n/a
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

"Daniel O'Connell" <onyxkirx@--NOSPAM--comcast.net> wrote in message
news:%2***************@TK2MSFTNGP12.phx.gbl...
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...5/copying.html

Jul 21 '05 #25

P: n/a
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:uF****************@TK2MSFTNGP12.phx.gbl...
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.


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.

> , or that without documentation you cannot know for sure
> that you are calling a copy constructor, not just a badly typed
> constructor, or an ambigious constructor call using some of the
> more complicated language rules that not everyone is familiar with

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.


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.

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 <g> ?

> , I'd
> call Copy Constructors a technique that lacks a good deal of
> grace.

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.

> Calling Clone tells me I have a copy of an object, new
> myObject(myObjectReference) 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).

"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.


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.


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".
> It
> also guarentees that I won't lose any data that makes sense to
> copy. A copy constructor very well could ignore many fields which
> shouldn't be dumped, simply because you called a base constructor
> instead of the concrete type constructor. I don't consider a copy
> without copying ALL relevent data a copy, but more of a near type
> conversion.

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?


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 howmuch clearer and safe copy construction is as
a technique than your method of cloning.


> It also doesn't help as far as interfaces go, how exactly do you
> clone an object that implements, say, IMyDataObject with a copy
> constructor?

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

> What constructor do you call?

See above.

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.


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).

> Is there an argument for why copy constructors are better, other
> than simply because they are easier(for you) to type? The ease of
> constructors calling eachother doesn't hold up

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);
}


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.

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, ;)


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.
Jul 21 '05 #26

P: n/a
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 ?
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.

1. http://www.ondotnet.com/pub/a/dotnet...5/copying.html

Jul 21 '05 #27

P: n/a
Edward Diener <ed******@tropicsoft.com> wrote:
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.


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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #28

P: n/a
Jon Skeet [C# MVP] wrote:
Edward Diener <ed******@tropicsoft.com> wrote:
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.


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.
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.


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.
Once again, Ugh !!! And this flawed technique is better
than protected copy constructors ?


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


How does one lose information via copy constructors ?
Jul 21 '05 #29

P: n/a
Edward Diener <ed******@tropicsoft.com> wrote:
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.


Yes it is, because that's what MemberwiseClone does.
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 ?


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.
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.


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.
Mind you, I don't think you
should have any protected variables in the first place...


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
</quote>
Once again, Ugh !!! And this flawed technique is better
than protected copy constructors ?


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


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?

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #30

P: n/a
>
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.
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".


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.
>> It
>> also guarentees that I won't lose any data that makes sense to
>> copy. A copy constructor very well could ignore many fields which
>> shouldn't be dumped, simply because you called a base constructor
>> instead of the concrete type constructor. I don't consider a copy
>> without copying ALL relevent data a copy, but more of a near type
>> conversion.
>
> 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?

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.

>> It also doesn't help as far as interfaces go, how exactly do you
>> clone an object that implements, say, IMyDataObject with a copy
>> constructor?
>
> Interfaces are member function contracts and do not contain data
> AFAIK.
>
>> What constructor do you call?
>
> See above.
>
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.
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.
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)

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).


>> Is there an argument for why copy constructors are better, other
>> than simply because they are easier(for you) to type? The ease of
>> constructors calling eachother doesn't hold up
>
> 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);
}

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.

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, ;)


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.

Jul 21 '05 #31

P: n/a

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:uf**************@TK2MSFTNGP10.phx.gbl...
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.

And as Jon Skeet pointed out, you shouldn't be exposing variables as
protected anyway.
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.

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.

1. http://www.ondotnet.com/pub/a/dotnet...5/copying.html


Jul 21 '05 #32

P: n/a
Jon Skeet [C# MVP] wrote:
Edward Diener <ed******@tropicsoft.com> wrote:
Mind you, I don't think you
should have any protected variables in the first place...
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
</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.
Once again, Ugh !!! And this flawed technique is better
than protected copy constructors ?

Yes, unless you don't care about losing information.
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.


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.
Jul 21 '05 #33

P: n/a
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:uf**************@TK2MSFTNGP10.phx.gbl...
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.
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.

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.
Jul 21 '05 #34

P: n/a
Edward Diener <ed******@tropicsoft.com> wrote:
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.


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.
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.


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.

<snip>
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 ?


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.
<snip>
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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #35

P: n/a

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:ua**************@TK2MSFTNGP12.phx.gbl...
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:uf**************@TK2MSFTNGP10.phx.gbl...
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.

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.
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;

}
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.

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.

Jul 21 '05 #36

P: n/a
Jon Skeet [C# MVP] wrote:
Edward Diener <ed******@tropicsoft.com> wrote:

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.


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.
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.


Agreed.

<snip>
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 ?


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.


<snip>
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.


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.
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.


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.
Jul 21 '05 #37

P: n/a
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:ua**************@TK2MSFTNGP12.phx.gbl...

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.


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...
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.


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> .
Jul 21 '05 #38

P: n/a

"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:u$****************@TK2MSFTNGP11.phx.gbl...
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:ua**************@TK2MSFTNGP12.phx.gbl...

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.


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.
snipped...

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.
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> .
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.

Jul 21 '05 #39

P: n/a
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:u$****************@TK2MSFTNGP11.phx.gbl...
Daniel O'Connell wrote:
"Edward Diener" <ed******@tropicsoft.com> wrote in message
news:ua**************@TK2MSFTNGP12.phx.gbl...


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.


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.
Jul 21 '05 #40

P: n/a
Jon,
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.
Maybe this was addressed in the article Daniel posted the link to, which I
hope to get to read this week.

I don't see that MemberwiseClone is compatible with readonly instance
fields, if I want the readonly instance fields to be deep copied. Hence in
my project I went with a protected copy constructor. The project is largely
a closed system, so I don't have a problem with it per se.

Other then this cloning issue, are there other reasons I should consider
avoiding readonly instance fields? As you stated, I don't want to discuss
this in this thread, just wondering if you have any thinks to discussions on
readonly instance fields.

Thanks
Jay

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om... Edward Diener <ed******@tropicsoft.com> wrote:
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.


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.
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.


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.

<snip>
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 ?


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.


<snip>
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.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Jul 21 '05 #41

P: n/a
Jay B. Harlow [MVP - Outlook] <Ja************@msn.com> wrote:
Jon,
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.


Maybe this was addressed in the article Daniel posted the link to, which I
hope to get to read this week.

I don't see that MemberwiseClone is compatible with readonly instance
fields, if I want the readonly instance fields to be deep copied. Hence in
my project I went with a protected copy constructor. The project is largely
a closed system, so I don't have a problem with it per se.

Other then this cloning issue, are there other reasons I should consider
avoiding readonly instance fields? As you stated, I don't want to discuss
this in this thread, just wondering if you have any thinks to discussions on
readonly instance fields.


I don't, I'm afraid - I suspect you're in trouble in that situation,
unfortunately.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #42

P: n/a
Edward Diener <ed******@tropicsoft.com> wrote:
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.


Yes, it is. And if the base class *later* starts implementing
ICloneable, you could have problems - although when you recompile
against the later version of the base class you'll get a compiler
warning. In fact, that's enough to see whether or not the base class
has its own Clone method - if you get a warning when you try to write

public virtual object Clone()

then you need to take a closer look at the base class :)

Jay's objection on the grounds of readonly fields is a good one
though... I don't know a decent way of fixing it :(

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jul 21 '05 #43

This discussion thread is closed

Replies have been disabled for this discussion.