Connecting Tech Pros Worldwide Forums | Help | Site Map

How deep should a deep copy go? / Is an object that contains value type still a reference type?

ahaupt@gmail.com
Guest
 
Posts: n/a
#1: Nov 17 '05
Hi all,

I'm implementing the Clone() method through the ICloneable interface
and don't quite know how deep I need to go for a deep copy.

Example:

class A: ICloneable
{
object _val;

//Val will always be a value type
A(object val)
{
_val = val;
}

object Clone()
{
//Don't know if I this is sufficient
return new A(_val);

//Or do I have to go
object newVal;

if(val.GetType() == typeof(bool))
{
newVal = (bool) val;
}
//....etc....//

return new A(newVal)
}
}

Thus do I have to cast the object back to a value type before returning
the cloned instance.

So I suppose the real question is: Is an object that contains value
type still a reference type?

Thanks,
Andre




ahaupt@gmail.com
Guest
 
Posts: n/a
#2: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Also,

If I need to cast the object back to value type, before creating the
new instance, is there a way of casting it automatically?

An example might make the question a bit clearer:

Instead of going:

public object CreateNewValueTypeObject(object obj)
{
object newObj;

if(obj.GetType() == typeof(bool))
{
newObj = (bool) obj;
}
else ....

}

Is it possible to do something like:

object newObj = (obj.GetType()) obj;

Thanks all,
Andre

shiv_koirala@yahoo.com
Guest
 
Posts: n/a
#3: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Hi

To implement deep copy you can use serialization , thats how deep copy
is implemented. Shallow copy is done by reference , but deep copy means
create a complete new object in short real clooning.

Once we serialize the object all references are also serialzed.

Shivprasad Koirala
C# , VB.NET , SQL SERVER , ASP.NET Interview Questions
http://www.geocities.com/dotnetinterviews/

ahaupt@gmail.com
Guest
 
Posts: n/a
#4: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Hi Shivprasad,

Thanks for your reply.

I did a search on searlization and came up with this:

http://weblogs.asp.net/whaggard/arch...3/02/3313.aspx

It looks pretty good. I think I'll give that a try.

Kind regards,
Andre

Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#5: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Andre,

There is no way to do what you are doing, but since you are assigning it
to an object, what's the point?

In .NET 2.0, you can use generics to provide a type-safe cast though
(you indicate the type parameter for the method).

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com

<ahaupt@gmail.com> wrote in message
news:1125406249.596047.250180@o13g2000cwo.googlegr oups.com...[color=blue]
> Also,
>
> If I need to cast the object back to value type, before creating the
> new instance, is there a way of casting it automatically?
>
> An example might make the question a bit clearer:
>
> Instead of going:
>
> public object CreateNewValueTypeObject(object obj)
> {
> object newObj;
>
> if(obj.GetType() == typeof(bool))
> {
> newObj = (bool) obj;
> }
> else ....
>
> }
>
> Is it possible to do something like:
>
> object newObj = (obj.GetType()) obj;
>
> Thanks all,
> Andre
>[/color]


ahaupt@gmail.com
Guest
 
Posts: n/a
#6: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Hi Nicholas,

Thanks for the reply.

I'm assigning it to an object because I want to be able to cater for
all value types and I don't want to create unique constructors, class
members, and class methods for each type of value type.

Also, would you mind having a look at my root/first post? (When
implementing the Clone() method; Do you know if I have to a) create a
new object and cast it to the relevant value type, or b) could I just
use the existing object (when the object contains value types only)?)

Many thanks,
Andre

Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#7: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Andre,

I've seen your first post, and quite frankly, it looks confusing. val
is a field in the class (it can't be passed in), so you know the type,
instantly. There is no reason to cast to an object and then back again.

If you are trying to write a template for all classes to perform a deep
copy, it would be better if you create a static helper method somewhere
which used reflection to do this.


--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com

<ahaupt@gmail.com> wrote in message
news:1125412618.306005.7430@z14g2000cwz.googlegrou ps.com...[color=blue]
> Hi Nicholas,
>
> Thanks for the reply.
>
> I'm assigning it to an object because I want to be able to cater for
> all value types and I don't want to create unique constructors, class
> members, and class methods for each type of value type.
>
> Also, would you mind having a look at my root/first post? (When
> implementing the Clone() method; Do you know if I have to a) create a
> new object and cast it to the relevant value type, or b) could I just
> use the existing object (when the object contains value types only)?)
>
> Many thanks,
> Andre
>[/color]


ahaupt@gmail.com
Guest
 
Posts: n/a
#8: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Replying to my own post. Quite sad.

Anyway, I found a way to create a create new object so that it'll be of
the same type as ANY other original object.

Confusing? Look at this bit of code:

public object CreateNewObject(object obj)
{
object newObject = Activator.CreateInstance( obj.GetType() );
}

You do however need a parameterless Constructor in the orginal class
(obj's class).


ahaupt@gmail.com wrote:[color=blue]
> Also,
>
> If I need to cast the object back to value type, before creating the
> new instance, is there a way of casting it automatically?
>
> An example might make the question a bit clearer:
>
> Instead of going:
>
> public object CreateNewValueTypeObject(object obj)
> {
> object newObj;
>
> if(obj.GetType() == typeof(bool))
> {
> newObj = (bool) obj;
> }
> else ....
>
> }
>
> Is it possible to do something like:
>
> object newObj = (obj.GetType()) obj;
>
> Thanks all,
> Andre[/color]

ahaupt@gmail.com
Guest
 
Posts: n/a
#9: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Replying to my own post. Quite sad.

Anyway, I found a way to create a create new object so that it'll be of
the same type as ANY other original object.

Confusing? Look at this bit of code:

public object CreateNewObject(object obj)
{
object newObject = Activator.CreateInstance( obj.GetType() );
}

You do however need a parameterless Constructor in the orginal class
(obj's class).


ahaupt@gmail.com wrote:[color=blue]
> Also,
>
> If I need to cast the object back to value type, before creating the
> new instance, is there a way of casting it automatically?
>
> An example might make the question a bit clearer:
>
> Instead of going:
>
> public object CreateNewValueTypeObject(object obj)
> {
> object newObj;
>
> if(obj.GetType() == typeof(bool))
> {
> newObj = (bool) obj;
> }
> else ....
>
> }
>
> Is it possible to do something like:
>
> object newObj = (obj.GetType()) obj;
>
> Thanks all,
> Andre[/color]

Lasse Vågsæther Karlsen
Guest
 
Posts: n/a
#10: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


ahaupt@gmail.com wrote:[color=blue]
> Hi all,
>
> I'm implementing the Clone() method through the ICloneable interface[/color]
<snip>

Doing a "deep clone" is a serious matter and needs specific knowledge of
the target types, at least in a lot of scenarios. Cloning any type of
object is not that easy.

Let me give you an example.

Suppose you have the following classes:

- Order
- OrderLine

Their relationships are:

- An Order can hold references to many OrderLine objects
- An OrderLine object holds a reference to the Order that its a part of

Now...

If you want to clone an order, you would:

- Clone the Order
- Clone all the OrderLines attached to it and attach them to the cloned
order
- Fix up the references (so that the cloned OrderLine's reference to its
order points to the new, cloned, order)

If you want to clone an orderline, you would:

- Clone the orderline, leaving the reference to its order in place for
the new line (in other words, you duplicate a line which ends up
attached to the same order as the original)

This means that the process of cloning an orderline depends on wether
you are only cloning an orderline or wether you are cloning the whole order.

If you implement "deep cloning" in both without knowledge about where
you started you might end up with:

- Call .Clone on Order, produces new Order object and proceeds to call
..Clone on each OrderLine and attaching them to the new Order object
- For each .Clone call on each OrderLine, you clone that object, which
in turn clones the Order again, going back and produces a new Order
- Repeat ad nauseum

In other words, you can't write the cloning process for the orderline
without knowledge about the objects around it and what you are actually
cloning (where you started in other words).

Cloning is something you need to work into a class hierarchy as a whole
and you cannot do it separately for all the objects, or you will get a
broken implementation.

To add to the above problem, add a Customer to the whole thing. A Order
or OrderLine might contain a reference to the Customer, and possibly the
Customer might contain reference to all his orders. What happens if:

- You clone the order (leave it attached to the same customer)
- You clone the customer (clone all orders which will use a different
customer reference)

I've looked at several ways to implement cloning and have found that the
following three ways seems to work ok and leave little doubt about what
is actually happening:

1. Use a mechanism with attributes to tag properties in a class that
should be "fixed up" during cloning, in such a way that I can know what
to do depending on what kind of object the cloning process was started
from (ie. I can detail what happens if I clone a Customer vs. a Order
vs. a OrderLine). The attributes still need to be written so that they
cover each scenario (all the possible starting points for cloning)
2. Use a separate cloning helper class for the hierarchy with methods
that clearly detail what they do (CloneCustomer, CloneOrder,
CloneOrderLine) and leave the cloning mechanism completely out of the object
3. Give the Clone methods the type of the initial class I called .Clone
on so that they know what to clone and what to copy (this is just a
non-attribute version of #1).

The ICloneable interface gives you a lot of questions, many of which the
answer to is "ICloneable is not enough" so I've decided that I won't use
it for my own objects except for trivial scenarios (ie. objects which
clearly aren't meant to participate in big hierarchies and graphs).

--
Lasse Vågsæther Karlsen
http://www.vkarlsen.no/
mailto:lasse@vkarlsen.no
PGP KeyID: 0x2A42A1C2
Lasse Vågsæther Karlsen
Guest
 
Posts: n/a
#11: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


ahaupt@gmail.com wrote:[color=blue]
> Hi all,
>
> I'm implementing the Clone() method through the ICloneable interface[/color]
<snip>

Doing a "deep clone" is a serious matter and needs specific knowledge of
the target types, at least in a lot of scenarios. Cloning any type of
object is not that easy.

Let me give you an example.

Suppose you have the following classes:

- Order
- OrderLine

Their relationships are:

- An Order can hold references to many OrderLine objects
- An OrderLine object holds a reference to the Order that its a part of

Now...

If you want to clone an order, you would:

- Clone the Order
- Clone all the OrderLines attached to it and attach them to the cloned
order
- Fix up the references (so that the cloned OrderLine's reference to its
order points to the new, cloned, order)

If you want to clone an orderline, you would:

- Clone the orderline, leaving the reference to its order in place for
the new line (in other words, you duplicate a line which ends up
attached to the same order as the original)

This means that the process of cloning an orderline depends on wether
you are only cloning an orderline or wether you are cloning the whole order.

If you implement "deep cloning" in both without knowledge about where
you started you might end up with:

- Call .Clone on Order, produces new Order object and proceeds to call
..Clone on each OrderLine and attaching them to the new Order object
- For each .Clone call on each OrderLine, you clone that object, which
in turn clones the Order again, going back and produces a new Order
- Repeat ad nauseum

In other words, you can't write the cloning process for the orderline
without knowledge about the objects around it and what you are actually
cloning (where you started in other words).

Cloning is something you need to work into a class hierarchy as a whole
and you cannot do it separately for all the objects, or you will get a
broken implementation.

To add to the above problem, add a Customer to the whole thing. A Order
or OrderLine might contain a reference to the Customer, and possibly the
Customer might contain reference to all his orders. What happens if:

- You clone the order (leave it attached to the same customer)
- You clone the customer (clone all orders which will use a different
customer reference)

I've looked at several ways to implement cloning and have found that the
following three ways seems to work ok and leave little doubt about what
is actually happening:

1. Use a mechanism with attributes to tag properties in a class that
should be "fixed up" during cloning, in such a way that I can know what
to do depending on what kind of object the cloning process was started
from (ie. I can detail what happens if I clone a Customer vs. a Order
vs. a OrderLine). The attributes still need to be written so that they
cover each scenario (all the possible starting points for cloning)
2. Use a separate cloning helper class for the hierarchy with methods
that clearly detail what they do (CloneCustomer, CloneOrder,
CloneOrderLine) and leave the cloning mechanism completely out of the object
3. Give the Clone methods the type of the initial class I called .Clone
on so that they know what to clone and what to copy (this is just a
non-attribute version of #1).

The ICloneable interface gives you a lot of questions, many of which the
answer to is "ICloneable is not enough" so I've decided that I won't use
it for my own objects except for trivial scenarios (ie. objects which
clearly aren't meant to participate in big hierarchies and graphs).

--
Lasse Vågsæther Karlsen
http://www.vkarlsen.no/
mailto:lasse@vkarlsen.no
PGP KeyID: 0x2A42A1C2
Lasse Vågsæther Karlsen
Guest
 
Posts: n/a
#12: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


shiv_koirala@yahoo.com wrote:[color=blue]
> Hi
>
> To implement deep copy you can use serialization , thats how deep copy
> is implemented. Shallow copy is done by reference , but deep copy means
> create a complete new object in short real clooning.
>
> Once we serialize the object all references are also serialzed.
>
> Shivprasad Koirala
> C# , VB.NET , SQL SERVER , ASP.NET Interview Questions
> http://www.geocities.com/dotnetinterviews/
>[/color]

Using serialization is good if you want to clone a whole object graph.
In some cases you only need to do a partial clone as far as the whole
graph is concerned (ie. clone an order attached to a customer, but let
it refer to the same customer as the original order). At that point you
will have some problems using serialization, which tends to do a
complete graph serialization, containing the customer and whatnot.

Of course, if you want to clone the complete object, including all
related objects, very little beat using serialization in terms of
simplicity of implementation.

--
Lasse Vågsæther Karlsen
http://www.vkarlsen.no/
mailto:lasse@vkarlsen.no
PGP KeyID: 0x2A42A1C2
Lasse Vågsæther Karlsen
Guest
 
Posts: n/a
#13: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


shiv_koirala@yahoo.com wrote:[color=blue]
> Hi
>
> To implement deep copy you can use serialization , thats how deep copy
> is implemented. Shallow copy is done by reference , but deep copy means
> create a complete new object in short real clooning.
>
> Once we serialize the object all references are also serialzed.
>
> Shivprasad Koirala
> C# , VB.NET , SQL SERVER , ASP.NET Interview Questions
> http://www.geocities.com/dotnetinterviews/
>[/color]

Using serialization is good if you want to clone a whole object graph.
In some cases you only need to do a partial clone as far as the whole
graph is concerned (ie. clone an order attached to a customer, but let
it refer to the same customer as the original order). At that point you
will have some problems using serialization, which tends to do a
complete graph serialization, containing the customer and whatnot.

Of course, if you want to clone the complete object, including all
related objects, very little beat using serialization in terms of
simplicity of implementation.

--
Lasse Vågsæther Karlsen
http://www.vkarlsen.no/
mailto:lasse@vkarlsen.no
PGP KeyID: 0x2A42A1C2
ahaupt@gmail.com
Guest
 
Posts: n/a
#14: Nov 17 '05

re: How deep should a deep copy go? / Is an object that contains value type still a reference type?


Hi Lasse,

Thanks for the post. It was really insightful.

I'll keep it in mind, next time I develop a more complex structure.

Many thanks,
Andre

Lasse Vågsæther Karlsen wrote:[color=blue]
> ahaupt@gmail.com wrote:[color=green]
> > Hi all,
> >
> > I'm implementing the Clone() method through the ICloneable interface[/color]
> <snip>
>
> Doing a "deep clone" is a serious matter and needs specific knowledge of
> the target types, at least in a lot of scenarios. Cloning any type of
> object is not that easy.
>
> Let me give you an example.
>
> Suppose you have the following classes:
>
> - Order
> - OrderLine
>
> Their relationships are:
>
> - An Order can hold references to many OrderLine objects
> - An OrderLine object holds a reference to the Order that its a part of
>
> Now...
>
> If you want to clone an order, you would:
>
> - Clone the Order
> - Clone all the OrderLines attached to it and attach them to the cloned
> order
> - Fix up the references (so that the cloned OrderLine's reference to its
> order points to the new, cloned, order)
>
> If you want to clone an orderline, you would:
>
> - Clone the orderline, leaving the reference to its order in place for
> the new line (in other words, you duplicate a line which ends up
> attached to the same order as the original)
>
> This means that the process of cloning an orderline depends on wether
> you are only cloning an orderline or wether you are cloning the whole order.
>
> If you implement "deep cloning" in both without knowledge about where
> you started you might end up with:
>
> - Call .Clone on Order, produces new Order object and proceeds to call
> .Clone on each OrderLine and attaching them to the new Order object
> - For each .Clone call on each OrderLine, you clone that object, which
> in turn clones the Order again, going back and produces a new Order
> - Repeat ad nauseum
>
> In other words, you can't write the cloning process for the orderline
> without knowledge about the objects around it and what you are actually
> cloning (where you started in other words).
>
> Cloning is something you need to work into a class hierarchy as a whole
> and you cannot do it separately for all the objects, or you will get a
> broken implementation.
>
> To add to the above problem, add a Customer to the whole thing. A Order
> or OrderLine might contain a reference to the Customer, and possibly the
> Customer might contain reference to all his orders. What happens if:
>
> - You clone the order (leave it attached to the same customer)
> - You clone the customer (clone all orders which will use a different
> customer reference)
>
> I've looked at several ways to implement cloning and have found that the
> following three ways seems to work ok and leave little doubt about what
> is actually happening:
>
> 1. Use a mechanism with attributes to tag properties in a class that
> should be "fixed up" during cloning, in such a way that I can know what
> to do depending on what kind of object the cloning process was started
> from (ie. I can detail what happens if I clone a Customer vs. a Order
> vs. a OrderLine). The attributes still need to be written so that they
> cover each scenario (all the possible starting points for cloning)
> 2. Use a separate cloning helper class for the hierarchy with methods
> that clearly detail what they do (CloneCustomer, CloneOrder,
> CloneOrderLine) and leave the cloning mechanism completely out of the object
> 3. Give the Clone methods the type of the initial class I called .Clone
> on so that they know what to clone and what to copy (this is just a
> non-attribute version of #1).
>
> The ICloneable interface gives you a lot of questions, many of which the
> answer to is "ICloneable is not enough" so I've decided that I won't use
> it for my own objects except for trivial scenarios (ie. objects which
> clearly aren't meant to participate in big hierarchies and graphs).
>
> --
> Lasse Vågsæther Karlsen
> http://www.vkarlsen.no/
> mailto:lasse@vkarlsen.no
> PGP KeyID: 0x2A42A1C2[/color]

Closed Thread


Similar C# / C Sharp bytes