473,804 Members | 2,271 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Pass by Reference as "essential" to swap method exposed as a lie

In the otherwise excellent book C# 3.0 in a Nutshell by Albahari et
al. (3rd edition) (highly recommended--it's packed with information,
and is a desktop reference book) the following statement is made: (p.
39: "The ref modifier is essential in implementing a swap method")

This is untrue. The following program demonstrates it. See how
method "func4Swap" does a swap of two int variables without using ref,
but using a 'helper' class and using only pass by value

However, ref is important when using 'new' in the method calling the
variables to be used (not shown here), or, if you want to permanently
change the variables passed from inside the class doing the passing
(see func1 method and swap1 method below). In fact, I'm not sure you
can do a swap without using ref and without using a 'helper' class as
in the below.

RL

// OUTPUT AT END

// Pass by reference, Pass by Value demonstrated // October 15, 2008

using System;
using System.Collecti ons.Generic;
using System.Linq;
using System.Text;
using System.Runtime. InteropServices ;
namespace console1
{
class Program
{
static void Main(string[] args)
{
////////////////////////////////////////////
// show pass by ref

PassByRef01 myPBRclas1 = new PassByRef01();

Console.WriteLi ne("I. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k,my PBRclas1.m);
myPBRclas1.func 2(myPBRclas1.i, myPBRclas1.j);
Console.WriteLi ne("II. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
myPBRclas1.func 1(ref myPBRclas1.k, ref myPBRclas1.m);
Console.WriteLi ne("III. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);

PassByRef01 placeHolderPass ByRef01cl = new PassByRef01();

placeHolderPass ByRef01cl.func3 (myPBRclas1);
Console.WriteLi ne("IV. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);

placeHolderPass ByRef01cl.func2 (myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("V. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("VI. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("reset values");
myPBRclas1.k = 100;
myPBRclas1.m = 200;
Console.WriteLi ne("1. k,m's are: {0}, {1}", myPBRclas1.k,
myPBRclas1.m);
placeHolderPass ByRef01cl.func4 Swap(myPBRclas1 );
Console.WriteLi ne("2. i,j's and k,m's are: {0}, {1}",myPBRclas1 .k,
myPBRclas1.m);
Console.WriteLi ne("now use 'traditional' swap");
placeHolderPass ByRef01cl.func4 TraditionalSwap (ref myPBRclas1);
Console.WriteLi ne("3. i,j's and k,m's are: {0}, {1}",
myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("now use traditional swap from inside of class
(no helper class used)");
myPBRclas1.swap 1(ref myPBRclas1.k, ref myPBRclas1.m);
Console.WriteLi ne("4. i,j's and k,m's are: {0}, {1}",
myPBRclas1.k, myPBRclas1.m);
}

}
}
/////////////////
using System;
using System.Collecti ons.Generic;
using System.Linq;
using System.Text;

namespace console1
{
class PassByRef01
{
public int k, m;
int _i, _j;
public PassByRef01()
{
_i = 10;
_j = 11;
k = 1;
m = 2;
}
public void swap1(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}

public void func1(ref int a, ref int b)
{
a = 1111;
b = 2222;
Console.WriteLi ne("inside func1, k,m's are: {0}, {1}", k,
m);
}
public void func2(int a, int b)
{
a = 1110000; //since ref not used, this assignment never
made for k,m
b = 2220000;
Console.WriteLi ne("inside func2, k,m's are: {0}, {1}",
k,m);
}

public void func3(PassByRef 01 x)
{
x.k = 66;
x.m = 67;
Console.WriteLi ne("inside func3, k,m's are: {0}, {1}", k,
m);
}

public void func4Traditiona lSwap(ref PassByRef01 y)
{
int temp;
temp = y.k;
y.k = y.m;
y.m = temp;
}

public void func4Swap(PassB yRef01 x)
{
int temp1, temp2;
temp1 = x.k;
temp2 = x.m;
x.m = temp1;
x.k = temp2;

Console.WriteLi ne("inside func3, k,m's are: {0}, {1} and
x.k, x.m are: {2}, {3}", k, m, x.k, x.m);
}
public int i //cannot pass by ref a property
{
get { return _i; }
set { _i = value; }
}
public int j
{
get { return _j; }
set { _j = value; }
}
}

}
/////////////////////// OUTPUT

I. i,j's and k,m's are: 10, 11, 1, 2
inside func2, k,m's are: 1, 2
II. i,j's and k,m's are: 10, 11, 1, 2
inside func1, k,m's are: 1111, 2222
III. i,j's and k,m's are: 10, 11, 1111, 2222
inside func3, k,m's are: 1, 2
IV. i,j's and k,m's are: 10, 11, 66, 67
inside func2, k,m's are: 1, 2
V. i,j's and k,m's are: 10, 11, 66, 67
VI. i,j's and k,m's are: 10, 11, 66, 67
reset values
1. k,m's are: 100, 200
inside func3, k,m's are: 1, 2 and x.k, x.m are: 200, 100
2. i,j's and k,m's are: 200, 100
now use 'traditional' swap
3. i,j's and k,m's are: 100, 200
now use traditional swap from inside of class (no helper class used)
4. i,j's and k,m's are: 200, 100
Press any key to continue . . .

Oct 15 '08 #1
21 1896
You've done this to death already; and you're still quite, quite
wrong. Ref applies only to the arguments - i.e. "x".

Marc
Oct 15 '08 #2
On Oct 15, 5:50*am, Marc Gravell <marc.grav...@g mail.comwrote:
You've done this to death already; and you're still quite, quite
wrong. Ref applies only to the arguments - i.e. "x".

Marc
Semantics my friend. You are clearly wrong.

What part of this code don't you understand?
public void func4Swap(PassB yRef01 x)
{
int temp1, temp2;
temp1 = x.k;
temp2 = x.m;
x.m = temp1;
x.k = temp2;
Console.WriteLi ne("inside func3, k,m's are: {0}, {1} and
x.k, x.m are: {2}, {3}", k, m, x.k, x.m);
}
It works to change x.m to x.k. That was the exercise.

All the words in the world and all the spin won't change this
verisimilitude.

RL
Oct 15 '08 #3
You are not passing using the "ref" qualifier but you are passing a
reference which may be changed.

To prove you are correct the only way would be to write code which passes
this test:

[TestMethod]
public void ProvePassByRefe renceIsEsstenti alIsALie()
{
int value1 = 1;
int value2 = 2;

Swap(value1, value2);

Assert.AreEqual (2, value1);
Assert.AreEqual (1, value2);
}

You are not allowed to change the test source code at all. You will not be
able to do it, I am certain.

PS: Saying it is a "lie" is ridiculous. At worst it would be a mistake, not
a lie!

Pete
====
http://mrpmorris.blogspot.com
http://www.capableobjects.com
Oct 15 '08 #4
It works to change x.m to x.k. *That was the exercise.

Only to you. In the context of the book, the exercise was undoubtedly
to swap the values of the *arguments*, not to swap two fields on a
single (class) argument.

Anyway, that is me done on this thread...

Marc
Oct 15 '08 #5
Your example is not swapping parameters. If i had an array and wanted to swap
two elements in it. I could not just call your function. I would have to
create you class, copy the references from the array to the class's
variables, call the function and then copy the references back. That is
entirely useless, You might as well do the swap inline as it would be less
code and more efficient.
To do a pure swap function which switches the value of the reference
variables passed as parameters you need to use the ref keyword. Why are you
always trying to find a different way to do this?
--
Ciaran O''Donnell
http://wannabedeveloper.spaces.live.com
"raylopez99 " wrote:
On Oct 15, 5:50 am, Marc Gravell <marc.grav...@g mail.comwrote:
You've done this to death already; and you're still quite, quite
wrong. Ref applies only to the arguments - i.e. "x".

Marc

Semantics my friend. You are clearly wrong.

What part of this code don't you understand?
public void func4Swap(PassB yRef01 x)
{
int temp1, temp2;
temp1 = x.k;
temp2 = x.m;
x.m = temp1;
x.k = temp2;
Console.WriteLi ne("inside func3, k,m's are: {0}, {1} and
x.k, x.m are: {2}, {3}", k, m, x.k, x.m);
}
It works to change x.m to x.k. That was the exercise.

All the words in the world and all the spin won't change this
verisimilitude.

RL
Oct 15 '08 #6
On Oct 15, 6:45*am, Ciaran O''Donnell
<CiaranODonn... @discussions.mi crosoft.comwrot e:
Your example is not swapping parameters. If i had an array and wanted to swap
two elements in it. I could not just call your function. I would have to
create you class, copy the references from the array to the class's
variables, call the function and then copy the references back. That is
entirely useless, You might as well do the swap inline as it would be less
code and more efficient.
Thanks for the reply. BTW how do you do anything 'inline' in C#? In C
++ I had the convention down pat but if you can post a short example
it would be helpful for me.
To do a pure swap function which switches the value of the reference
variables passed as parameters you need to use the ref keyword. Why are you
always trying to find a different way to do this?
I'm just showing how using encapsulation you can get around a lot of
bugaboos in C# (this also holds for private variables, because in a
way 'properties' is such an encapsulation).

Now the best answer for the 'traditionalist s' was given by Marc and
Peter Morris--you simply redefine your problem so your 'definition'
holds. But, in a way, I stood that principle on its head and
redefined it to suit my needs.

After all, if you are a master coder (and I'm not yet, with about 2
solid months of C# experience) you can find exceptions to every rule.

RL
Oct 15 '08 #7
On Oct 15, 3:22*pm, raylopez99 <raylope...@yah oo.comwrote:

<snip>
Now the best answer for the 'traditionalist s' was given by Marc and
Peter Morris--you simply redefine your problem so your 'definition'
holds. *But, in a way, I stood that principle on its head and
redefined it to suit my needs.
Yes - you redefined the problem. What you've done may indeed be
useful, but in no way proves the book wrong.

Jon
Oct 15 '08 #8
>>
Now the best answer for the 'traditionalist s' was given by Marc and
Peter Morris--you simply redefine your problem so your 'definition'
holds.
<<

I didn't redefine the problem.
01: I haven't seen the original text in the book.
02: I used my brain and guessed what the book is saying, and that is you
cannot change "parameter values" from the caller's point of view unless you
use "ref".

>>
After all, if you are a master coder (and I'm not yet, with about 2
solid months of C# experience) you can find exceptions to every rule.
<<

Or, put another way, what I lack in skill I more than make up for in denial
;-)

--
Pete
====
http://mrpmorris.blogspot.com
http://www.capableobjects.com

Oct 15 '08 #9
That's a lot of work to 'swap' two ints; try ...

int a = 3;
int b = 5;

a ^= b;
b ^= a;
a ^= b;

// a = 5, b = 3
"raylopez99 " wrote:
In the otherwise excellent book C# 3.0 in a Nutshell by Albahari et
al. (3rd edition) (highly recommended--it's packed with information,
and is a desktop reference book) the following statement is made: (p.
39: "The ref modifier is essential in implementing a swap method")

This is untrue. The following program demonstrates it. See how
method "func4Swap" does a swap of two int variables without using ref,
but using a 'helper' class and using only pass by value

However, ref is important when using 'new' in the method calling the
variables to be used (not shown here), or, if you want to permanently
change the variables passed from inside the class doing the passing
(see func1 method and swap1 method below). In fact, I'm not sure you
can do a swap without using ref and without using a 'helper' class as
in the below.

RL

// OUTPUT AT END

// Pass by reference, Pass by Value demonstrated // October 15, 2008

using System;
using System.Collecti ons.Generic;
using System.Linq;
using System.Text;
using System.Runtime. InteropServices ;
namespace console1
{
class Program
{
static void Main(string[] args)
{
////////////////////////////////////////////
// show pass by ref

PassByRef01 myPBRclas1 = new PassByRef01();

Console.WriteLi ne("I. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k,my PBRclas1.m);
myPBRclas1.func 2(myPBRclas1.i, myPBRclas1.j);
Console.WriteLi ne("II. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
myPBRclas1.func 1(ref myPBRclas1.k, ref myPBRclas1.m);
Console.WriteLi ne("III. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);

PassByRef01 placeHolderPass ByRef01cl = new PassByRef01();

placeHolderPass ByRef01cl.func3 (myPBRclas1);
Console.WriteLi ne("IV. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);

placeHolderPass ByRef01cl.func2 (myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("V. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("VI. i,j's and k,m's are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("reset values");
myPBRclas1.k = 100;
myPBRclas1.m = 200;
Console.WriteLi ne("1. k,m's are: {0}, {1}", myPBRclas1.k,
myPBRclas1.m);
placeHolderPass ByRef01cl.func4 Swap(myPBRclas1 );
Console.WriteLi ne("2. i,j's and k,m's are: {0}, {1}",myPBRclas1 .k,
myPBRclas1.m);
Console.WriteLi ne("now use 'traditional' swap");
placeHolderPass ByRef01cl.func4 TraditionalSwap (ref myPBRclas1);
Console.WriteLi ne("3. i,j's and k,m's are: {0}, {1}",
myPBRclas1.k, myPBRclas1.m);
Console.WriteLi ne("now use traditional swap from inside of class
(no helper class used)");
myPBRclas1.swap 1(ref myPBRclas1.k, ref myPBRclas1.m);
Console.WriteLi ne("4. i,j's and k,m's are: {0}, {1}",
myPBRclas1.k, myPBRclas1.m);
}

}
}
/////////////////
using System;
using System.Collecti ons.Generic;
using System.Linq;
using System.Text;

namespace console1
{
class PassByRef01
{
public int k, m;
int _i, _j;
public PassByRef01()
{
_i = 10;
_j = 11;
k = 1;
m = 2;
}
public void swap1(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}

public void func1(ref int a, ref int b)
{
a = 1111;
b = 2222;
Console.WriteLi ne("inside func1, k,m's are: {0}, {1}", k,
m);
}
public void func2(int a, int b)
{
a = 1110000; //since ref not used, this assignment never
made for k,m
b = 2220000;
Console.WriteLi ne("inside func2, k,m's are: {0}, {1}",
k,m);
}

public void func3(PassByRef 01 x)
{
x.k = 66;
x.m = 67;
Console.WriteLi ne("inside func3, k,m's are: {0}, {1}", k,
m);
}

public void func4Traditiona lSwap(ref PassByRef01 y)
{
int temp;
temp = y.k;
y.k = y.m;
y.m = temp;
}

public void func4Swap(PassB yRef01 x)
{
int temp1, temp2;
temp1 = x.k;
temp2 = x.m;
x.m = temp1;
x.k = temp2;

Console.WriteLi ne("inside func3, k,m's are: {0}, {1} and
x.k, x.m are: {2}, {3}", k, m, x.k, x.m);
}
public int i //cannot pass by ref a property
{
get { return _i; }
set { _i = value; }
}
public int j
{
get { return _j; }
set { _j = value; }
}
}

}
/////////////////////// OUTPUT

I. i,j's and k,m's are: 10, 11, 1, 2
inside func2, k,m's are: 1, 2
II. i,j's and k,m's are: 10, 11, 1, 2
inside func1, k,m's are: 1111, 2222
III. i,j's and k,m's are: 10, 11, 1111, 2222
inside func3, k,m's are: 1, 2
IV. i,j's and k,m's are: 10, 11, 66, 67
inside func2, k,m's are: 1, 2
V. i,j's and k,m's are: 10, 11, 66, 67
VI. i,j's and k,m's are: 10, 11, 66, 67
reset values
1. k,m's are: 100, 200
inside func3, k,m's are: 1, 2 and x.k, x.m are: 200, 100
2. i,j's and k,m's are: 200, 100
now use 'traditional' swap
3. i,j's and k,m's are: 100, 200
now use traditional swap from inside of class (no helper class used)
4. i,j's and k,m's are: 200, 100
Press any key to continue . . .

Oct 15 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
7105
by: Ruud de Jong | last post by:
The question I have is: how safe / future proof / portable is the use of the __subclasses__ method that exists for new-style classes? Background: I thought I had found an easy-to-understand application for metaclasses: making classes instantly aware of their subclasses. The context was that I needed a class hierarchy, and I wanted to be able to instantiate subclasses by calling the root class. Which exact subclass would be instantiated...
4
2503
by: Jian H. Li | last post by:
Hello, What's the essential differences between the two ways of "class::member" & "object.member"(or object_pointer->member)? class C{ public: void f() {} int i; };
9
2214
by: Aaron Gallimore | last post by:
Hi, Pretty simple one I think...Is there a "power of" or squared function in C++. This is what i'm trying to achieve. (array-array)*2 this doesnt work with minus numbers so i need a square or power function. also.. Is there a "sum of" function. Ultimately i'm trying to do a euclidean
24
2572
by: Alf P. Steinbach | last post by:
The eighth chapter (chapter 2.1) of my attempted Correct C++ tutorial is now available, although for now only in Word format -- comments welcome! Use the free & system-independent Open Office if you don't have Word. Classes <url: http://home.no.net/dubjai/win32cpptut/w32cpptut_02_01.zip> Introduces the C++ language feature used to define new types, namely classes. The focus in on creating safe and reusable classes. As a main
53
4606
by: Alf P. Steinbach | last post by:
So, I got the itch to write something more... I apologize for not doing more on the attempted "Correct C++ Tutorial" earlier, but there were reasons. This is an UNFINISHED and RAW document, and at the end there is even pure mindstorming text left in, but already I think it can be very useful. <url: http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01__alpha.doc.pdf>.
3
1590
by: Paramesh | last post by:
Hello friends, My friend asked me this question: This question regards proprietary software (of which I am one of the developers), so I cannot post actual code for this question. I will try to use illustrative examples. I have two libraries for distribution; one is an essential library and the other is an add-on (providing specialized extensions and
11
3664
by: RWC | last post by:
Hello, I'm having trouble converting code in Access XP / 2002. I have some code that declares an variable "as database" in Access 97, which is not recognized in Access XP. I've tried to find a refrence to the items that have changed between 97 and XP, and haven't been able to find anything yet. I will continue looking, but if anyone can shed some light on this fairly quickly, I would appreciate it. Thanks In Advance!
7
3020
by: Willem van Rumpt | last post by:
Hi all, coming from an unmanaged programming background, I took my time to sort out the IDisposable and finalizer patterns. Just when I thought I had it all conceptually neatly arranged, the "Close()" methods reared their ugly (at least it would seem...)heads. I was happily delving away in the .NET framework, investigating the stream classes with the msdn and Lutz Roeder's .NET reflector, when I stumbled upon the following:
8
3521
by: Bern McCarty | last post by:
Is it at all possible to leverage mixed-mode assemblies from AppDomains other than the default AppDomain? Is there any means at all of doing this? Mixed-mode is incredibly convenient, but if I cannot load/unload/reload extensions into my large and slow-to-load application during development without restarting the process then the disadvantages may outweigh the advantages. I've got a mixed-mode program in which I create a new AppDomain...
0
9714
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9594
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10599
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10347
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9173
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7635
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5673
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4308
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
3001
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.