Best Practices: always use new() with objects?

R

raylopez99

Hi,

Best practices question.

When receiving an object passed from another method, is it a good idea
to use a shallow copy with a temporary object received on the RHS
(right hand side of =), or to use a instantiated object to receive the
object on the RHS?

Since I may be using the wrong lingo, to put it more concretely.

FIRST WAY:

void somemethod
{

SomeClass X; //declares X as an object but does not instantiate it

X = Y // where Y is a reference passed by another method of type
SomeClass

// work with X within 'somemethod', and when the method 'somemethod'
ends, X is local and will disappear

}

SECOND WAY:

void somemethod
{
SomeClass X = new SomeClass(); // instantiated X

X = Y

// X will also disappear once void somemethod ends

}

Which is "better"? I say FIRST WAY. Which is safer? Perhaps SECOND
WAY, since it's less likely that X is a null reference, though if Y is
null then X can be null, so you have to check for it anyway.
 
A

Anthony Jones

raylopez99 said:
Hi,

Best practices question.

When receiving an object passed from another method, is it a good idea
to use a shallow copy with a temporary object received on the RHS
(right hand side of =), or to use a instantiated object to receive the
object on the RHS?

Since I may be using the wrong lingo, to put it more concretely.

FIRST WAY:

void somemethod
{

SomeClass X; //declares X as an object but does not instantiate it

X = Y // where Y is a reference passed by another method of type
SomeClass

// work with X within 'somemethod', and when the method 'somemethod'
ends, X is local and will disappear

}

SECOND WAY:

void somemethod
{
SomeClass X = new SomeClass(); // instantiated X

X = Y

// X will also disappear once void somemethod ends

}

Which is "better"? I say FIRST WAY. Which is safer? Perhaps SECOND
WAY, since it's less likely that X is a null reference, though if Y is
null then X can be null, so you have to check for it anyway.

Not sure why you believe avoiding a null reference is safer?

If Y is already inscope why would you want to do X = Y in the first place?

If there is a possibility that Y may be null you should write your code with
that in mind and take an appropriate action if it is. In some cases that
may be to use a new instance of the Y's type but I suspect there will be a
lot of cases where that isn't the right thing to do.
 
G

GlennDoten

raylopez99 said:
Hi,

Best practices question.

When receiving an object passed from another method, is it a good idea
to use a shallow copy with a temporary object received on the RHS
(right hand side of =), or to use a instantiated object to receive the
object on the RHS?

Since I may be using the wrong lingo, to put it more concretely.

FIRST WAY:

void somemethod
{

SomeClass X; //declares X as an object but does not instantiate it

X = Y // where Y is a reference passed by another method of type
SomeClass

// work with X within 'somemethod', and when the method 'somemethod'
ends, X is local and will disappear

}

SECOND WAY:

void somemethod
{
SomeClass X = new SomeClass(); // instantiated X

X = Y

// X will also disappear once void somemethod ends

}

Which is "better"? I say FIRST WAY. Which is safer? Perhaps SECOND
WAY, since it's less likely that X is a null reference, though if Y is
null then X can be null, so you have to check for it anyway.

I'm assuming you mean this:

class SomeClass { }
class FIRST_WAY
{
void somemethod(SomeClass Y)
{
SomeClass X;
X = Y;
}
}
class SECOND_WAY
{
void somemethod(SomeClass Y)
{
SomeClass X = new SomeClass();
X = Y;
}
}

I think the first is the best way to write this. And it can be made even
clearer (or at least one less line of code) like this:

SomeClass X = Y;

This means that X will now hold the same reference that Y holds, so
there are now at least two references to the same object that the GC
will keep track of. When somemethod exits, the reference in X will no
longer hold and the object will have one less reference. And once the
calling code's reference (communicated using Y) goes out of scope then
the object will not have that reference anymore. Assuming nothing else
has a reference to that same object then the GC can get rid of the
object at this point.

The second one doesn't make any sense to me. The first problem I see is
that you may not have the required information to create an instance of
SomeClass from within the somemethod method. And if you do, you simply
needlessly instantiate a SomeClass then immediately free up any
references to it by assigning Y to X and the GC will simply get rid of
the object on its next pass. So you've basically done a big NOOP.

I kinda have a feeling you are trying to ask a different question here,
or I have misinterpreted what you are asking.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

raylopez99 said:
Hi,

Best practices question.

When receiving an object passed from another method, is it a good idea
to use a shallow copy with a temporary object received on the RHS
(right hand side of =), or to use a instantiated object to receive the
object on the RHS?

You don't create copies of objects that way in .NET.
Since I may be using the wrong lingo, to put it more concretely.

FIRST WAY:

void somemethod
{

SomeClass X; //declares X as an object but does not instantiate it

X = Y // where Y is a reference passed by another method of type
SomeClass

That will only create a copy of the reference, not a copy of the object.
As Y already is a copy of the reference that you used in the call to
somemethod, it's pointless to make another copy of it.
// work with X within 'somemethod', and when the method 'somemethod'
ends, X is local and will disappear

The variable X is local, but it's referencing the same object as Y and
as the variable you used in the call. The reference X is local, but the
object is not.
}

SECOND WAY:

void somemethod
{
SomeClass X = new SomeClass(); // instantiated X

X = Y

That is even more pointless. You create an instance of the object and
put the reference to it in the X variable. Then you overwrite the
reference with the reference in the Y variable. You have only created an
object that is never used.
// X will also disappear once void somemethod ends

}

Which is "better"? I say FIRST WAY. Which is safer? Perhaps SECOND
WAY, since it's less likely that X is a null reference, though if Y is
null then X can be null, so you have to check for it anyway.

Neither. You are just making a copy of a copy of the reference. That
doesn't protect anything at all.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

raylopez99 said:
When receiving an object passed from another method, is it a good idea
to use a shallow copy with a temporary object received on the RHS
(right hand side of =), or to use a instantiated object to receive the
object on the RHS?

Since I may be using the wrong lingo, to put it more concretely.

FIRST WAY:

void somemethod
{

SomeClass X; //declares X as an object but does not instantiate it

X = Y // where Y is a reference passed by another method of type
SomeClass

// work with X within 'somemethod', and when the method 'somemethod'
ends, X is local and will disappear

}

SECOND WAY:

void somemethod
{
SomeClass X = new SomeClass(); // instantiated X

X = Y

// X will also disappear once void somemethod ends

}

Which is "better"? I say FIRST WAY. Which is safer? Perhaps SECOND
WAY, since it's less likely that X is a null reference, though if Y is
null then X can be null, so you have to check for it anyway.

Actually the two codes does the same thing except that the second one
create an object that you do not use for anything.

No difference for null handling.

None of them has anything to do with shallow clone.

Arne
 
R

raylopez99

I kinda have a feeling you are trying to ask a different question here,
or I have misinterpreted what you are asking.

No, you answered my question glenn.

But I posted this before I realized that in C# there is never any
implicit shallow copying (unlike C++), therefore, SomeClass X = Y; is
somewhat pointless, since you can use Y instead in the body of the
function. However, as I type this I realize that if you pass by value
rather than by reference, that is, if you do NOT use the 'ref'
keyword: void somemethod(ref SomeClass Y) // i.e. DON'T do this, but
rather, as in your example, void somemethod(SomeClass Y), then you can
use SomeClass X = Y; for code clarity, if you do stuff in the method
that returns SomeClass (to give a reader of your code some idea that
you're not returning Y as modified, but X, though one can argue that
the lack of the 'ref' keyword should clue in the reader that this is
the case.

Come to think of it, now that I see C# is like old-fashioned C in that
you are keeping track of passing a pointer (or reference) around, why
would you ever use SomeClass X = Y; ? Just use Y directly in your
method. All this time in C# I've been doing either "FIRST WAY" or,
(rarely, but in a few instances) "SECOND WAY" above, and this has
needlessly been somewhat slowing down my programs, though how much is
debatable with all the stuff going on behind the scenes in C#.NET
anyway.

RL
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

raylopez99 said:
But I posted this before I realized that in C# there is never any
implicit shallow copying (unlike C++), therefore, SomeClass X = Y; is
somewhat pointless, since you can use Y instead in the body of the
function.
Right.

However, as I type this I realize that if you pass by value
rather than by reference, that is, if you do NOT use the 'ref'
keyword: void somemethod(ref SomeClass Y) // i.e. DON'T do this, but
rather, as in your example, void somemethod(SomeClass Y), then you can
use SomeClass X = Y; for code clarity, if you do stuff in the method
that returns SomeClass (to give a reader of your code some idea that
you're not returning Y as modified, but X, though one can argue that
the lack of the 'ref' keyword should clue in the reader that this is
the case.

But that doesn't add any clarity. You are just copying the reference,
not the object, so it's still the same object.

If you change the object and return it, you have changed the original
object, which might be confusing as the signature of the method implies
that it should return a copy and leave the original unchanged.
Come to think of it, now that I see C# is like old-fashioned C in that
you are keeping track of passing a pointer (or reference) around, why
would you ever use SomeClass X = Y; ? Just use Y directly in your
method.
Exactly.

All this time in C# I've been doing either "FIRST WAY" or,
(rarely, but in a few instances) "SECOND WAY" above, and this has
needlessly been somewhat slowing down my programs, though how much is
debatable

Not much for the "first way". Another local variable only increases the
stack frame for the method, and that only costs a few bytes of stack
space, there is no extra code for that. The copying of the reference is
just a single instruction, so that doesn't take much time.

If the method is simple enough, the compiler might even be able to
completely optimise the extra variable away, just keeping the reference
in a processor register.
with all the stuff going on behind the scenes in C#.NET
anyway.

Besides the garbage collector, there isn't much going on behind the
scenes in .NET. There is no reference counting, so there is no extra
code added when references are copied, replaced or goes out of scope.
There no extra code added to run destructors when objects become
unreachable.

When you assign a reference, the only thing that happens is that four
bytes (on a 32 bit system) is copied, nothing else. When a reference
goes out of scope, nothing at all happens. I just goes silently into the
night.
 
P

Peter Duniho

raylopez99 said:
But I posted this before I realized that in C# there is never any
implicit shallow copying (unlike C++), therefore, SomeClass X = Y; is
somewhat pointless, since you can use Y instead in the body of the
function.

It's not necessarily pointless. There are situations in which it is
actually necessary or desirable. The examples in this thread aren't
those situations, but they do exist.
However, as I type this I realize that if you pass by value
rather than by reference, that is, if you do NOT use the 'ref'
keyword: void somemethod(ref SomeClass Y) // i.e. DON'T do this, but
rather, as in your example, void somemethod(SomeClass Y), then you can
use SomeClass X = Y; for code clarity, if you do stuff in the method
that returns SomeClass (to give a reader of your code some idea that
you're not returning Y as modified, but X, though one can argue that
the lack of the 'ref' keyword should clue in the reader that this is
the case.

I'm not really sure what you're getting at here. The "ref" keyword is
very different from passing a reference by value (which is what happens
without the "ref" keyword). You wouldn't use one in lieu of the other,
or as a way to self-document something related to the other.
Come to think of it, now that I see C# is like old-fashioned C in that
you are keeping track of passing a pointer (or reference) around, why
would you ever use SomeClass X = Y; ?

Well, as one example: suppose the parameter is a reference to the first
element in some sort of linked list structure where you can't easily get
from a node back to the list itself (e.g NOT the LinkedList<> generic
class, since the LinkedListNode<> class has a List property that returns
the containing list). Then you might want to preserve the parameter's
value by copying it to a local and using the local instead to traverse
the list. Then you can still get back to the first element of list
later in the method if needed.

There are plenty of other reasons you might not want to modify the
original parameter, even though you do need a variable that starts with
the original parameter and later gets modified. So there are situations
in which you would write "SomeClass X = Y;" where "Y" is some parameter.
Just use Y directly in your
method. All this time in C# I've been doing either "FIRST WAY" or,
(rarely, but in a few instances) "SECOND WAY" above, and this has
needlessly been somewhat slowing down my programs, though how much is
debatable with all the stuff going on behind the scenes in C#.NET
anyway.

As Göran says, the performance is likely to be negligible, and quite
possibly even non-existent as the compiler optimizes out any potential
inefficiencies like that. So if there's some sort of stylistic reason
you prefer copying the parameter even if it doesn't matter that you want
to modify it, or you're not modifying it, or whatever, that's fine.
Performance isn't likely to be a reason not to.

That said, I pretty much never copy parameters to some local variable
unless there's a algorithmic need to do so. :)

Pete
 
R

raylopez99

It's not necessarily pointless. There are situations in which it is
actually necessary or desirable. The examples in this thread aren't
those situations, but they do exist.


I'm not really sure what you're getting at here. The "ref" keyword is
very different from passing a reference by value (which is what happens
without the "ref" keyword). You wouldn't use one in lieu of the other,
or as a way to self-document something related to the other.


Well, as one example: suppose the parameter is a reference to the first
element in some sort of linked list structure where you can't easily get
from a node back to the list itself (e.g NOT the LinkedList<> generic
class, since the LinkedListNode<> class has a List property that returns
the containing list). Then you might want to preserve the parameter's
value by copying it to a local and using the local instead to traverse
the list. Then you can still get back to the first element of list
later in the method if needed.

There are plenty of other reasons you might not want to modify the
original parameter, even though you do need a variable that starts with
the original parameter and later gets modified. So there are situations
in which you would write "SomeClass X = Y;" where "Y" is some parameter.

Now I'm confused again. Are you saying that local variables indeed
preserve copies of Y, depending on the value of Y during the
"assignment"? (This is the way it works in C++, since SomeClass X=Y is
actually equivalent to SomeClass X(Y), where the copy constructor is
used for X).

An example:

LocalMethod (SomeClass Y) // pass by value
{

SomeClass X = Y;

// work with and change Y now, i.e. "Y++", etc

SomeClass Z = Y;

//work with and change Y now

SomeClass W = Y;

/*
Are we saying that: X != Z != W; //?!?

I thought this is contrary to the philosophy of C#?

Wait... I will write a quick demonstration program rather than simply
post...hold on now...
[Ten minutes later...]

class TestClass02 : ICloneable
{
public int i;
public TestClass02()
{
i = 10;
}

public void Method02(TestClass02 T1)
{
TestClass02 local1 = T1;
T1.i = T1.i + 1;
Console.WriteLine("Local i and T i are: {0}, {1}",
local1.i, T1.i); //output is 11, 11, not 10,11
//now clone local variable
TestClass02 local1Clone;
local1Clone = (TestClass02) local1.Clone();
local1Clone.i = local1Clone.i + 10000;
Console.WriteLine("Local i and T i and Local1Clone are:
{0}, {1}, {2}", local1.i, T1.i,local1Clone.i);
//output is 11, 11, 10011, as expected

/*
*
*
Local i and T i are: 11, 11
Local i and T i and Local1Clone are: 11, 11, 10011
Press any key to continue . . .
*
*
*/

}

By Jove/Zeus, I think I got it now!

RL
 
P

Peter Duniho

raylopez99 said:
Now I'm confused again. Are you saying that local variables indeed
preserve copies of Y, depending on the value of Y during the
"assignment"?

It depends on what you mean specifically. Local variables can be used
to preserve a copy of the _reference_ to the object Y. The object
remains the same, but you can replace the reference with a difference
reference, and as long as you still have a reference to the original
object is available in some other variable, then you can still get to
the original object.
(This is the way it works in C++, since SomeClass X=Y is
actually equivalent to SomeClass X(Y), where the copy constructor is
used for X).

An example:

LocalMethod (SomeClass Y) // pass by value
{

SomeClass X = Y;

// work with and change Y now, i.e. "Y++", etc

SomeClass Z = Y;

//work with and change Y now

SomeClass W = Y;

/*
Are we saying that: X != Z != W; //?!?

No. In that example all of the references still point to the same
original object, and after all the copying of the references, the
references are equal to each other. They are equal with respect to the
reference itself, and so of course the objects to which they refer are
identical as well.
I thought this is contrary to the philosophy of C#?

Wait... I will write a quick demonstration program rather than simply
post...hold on now...
[Ten minutes later...]

I think from your sample program, you see what I'm talking about. But
please feel free to ask for clarification if it's still not clear.

Pete
 
R

raylopez99

raylopez99 wrote:
Wait... I will write a quick demonstration program rather than simply
post...hold on now...
[Ten minutes later...]

I think from your sample program, you see what I'm talking about. But
please feel free to ask for clarification if it's still not clear.

Pete

Thanks for that clarification.

RL
 

Ask a Question

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

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

Ask a Question

Top