Class and struct
Article Index
Class and struct
Solution

Solution

The reason the method no longer works is that struct isn't just a lightweight form of class. A struct is a value type and this means that value rather than reference semantics apply. For example:

Mystruct2=Mystruct1;

where both are structs results in a complete and separate copy of Mystruct1 being stored in Mystruct2. 

However:

Myclass2=Myclass1;

where both are classes results in Myclass2 referencing the same object as Myclass1, i.e. there is not separate copy created of the object.

In the same way when you pass a value type into a method you pass a complete new copy which has nothing to do with the original. For example if mymethod is:

void mymethod(int i)
{
i=3;
}

then the result of the call:

i=2;
mymethod(i);

is that i is still 2.

However if i is part of a  reference type:

public class myclass
{
public int i;
}

and mymethod is modified to read:

public void mymethod(myclass O)
{
O.i = 4;
}

then after

myclass myobject = new myclass() { i = 3 };
mymethod(myobject);

i is changed to 4.

The behavior changes depending on whether or not you are passing a value or a reference type.

In the same way in our puzzle:

public void ZeroPoint(point p)
{       
p.x=0;
p.y=0;
}

doesn't change the values of x and y on the value type passed into the method but on a copy of the value type used within the method.

By contrast if point is a reference type, then p is a reference to the object passed in and, in this case, the changes are made on the original object and its x and y properites are changed.

Banner

Pattern

There is no easy solution to this problem if you want to write methods like ZeroPoint that make changes to objects passed as parameters - apart from being very aware of the difference between value and reference semantics.

You can make mymethod work in the same way as for a value type as for a reference type by changing the use to pass by reference:

public void ZeroPoint(ref point p)
{
p.x = 0;
p.y = 0;
}

but this also requires a change to every use of ZeroPoint to:

ZeroPoint(ref p1);

Another approach is to  test to see if the passed-in parameter was a value type and throw an exception if it was. But this would add an overhead for a rarely encountered event, i.e that the programmer changes a class to as struct or vice versa.

A more sensible approach is not to use methods that make changes to objects that are passed via parameters. Such changes are called "side effects" and it is good programming practice to avoid changes via side effects. 

A good method should change nothing and pass back a result.

This takes us deep into functional programming and other interesting ideas.

Further reading:

Inside C# 4 Data Structs

Value and Reference


 

Banner

More Puzzles

C#
Overriding Problems A C# Puzzle

Objects are indispensable but exactly how a language implements them and makes them available to the programmer matters. Sometimes the class-based approach complete with inheritance makes things compl [ ... ]


Sharpen Your Coding Skills
Towers Of Hanoi Mutants

Towers of Hanoi is a classic puzzle and is often used to illustrate the idea of recursion. Here Melvin Frammis challenges you to attempt to find solutions to some variations - but first he explains th [ ... ]


Python
Programmer Puzzle - Python Swallows A Global

Here's a teaser that poses a practical problem - one that crops up in everyday Python programming. See if you can work out the answer before looking at its solution and the pattern to follow to avoid  [ ... ]


Other Articles

 

<ASIN:0321637003>

<ASIN:0596800959>

<ASIN:047043452X>

<ASIN:0123745144>



 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.