通过引用传递为“必要”交换暴露为谎言的方法 [英] Pass by Reference as "essential" to swap method exposed as a lie

查看:102
本文介绍了通过引用传递为“必要”交换暴露为谎言的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在另一本优秀的书中,C#3.0 in a Nutshari et Nutshari

al。 (第3版)(强烈推荐 - 它包含信息,

并且是桌面参考书)以下声明:(p。

39 :ref修饰符对于实现交换方法至关重要


这是不真实的。以下程序演示了它。了解

方法" func4Swap"做一个交换两个int变量而不使用ref,

但是使用''helper''类并且只使用pass by value


但是,ref是重要的是在调用

变量的方法中使用''new''(这里没有显示),或者,如果你想永久地

改变传递的变量从班级里面做传递

(参见下面的func1方法和swap1方法)。事实上,我不确定你是否可以在不使用ref的情况下进行交换,而不使用帮助类,如下所示。

。 />

RL


//结束时输出


//通过引用传递,按值显示// 2008年10月15日


使用System;

使用System.Collections.Generic;

使用System.Linq;

使用System.Text;

使用System.Runtime.InteropServices;

命名空间console1

{

class program

{

static void Main(string [] args)

{

/ ///////////////////////////////////////////

// show pass by ref


PassByRef01 myPBRclas1 = new PassByRef01();


Console.WriteLine(" I.i,j 's和k,m'是:{0},{1},{2},{3}",

myPBRclas1.i,myPBRclas1.j,myPBRclas1.k, myPBRclas1.m);

myPBRclas1.func2(myPBRclas1.i,myPBRclas1.j);

C onsole.WriteLine(QUOT; II。 i,j'和k,m'是:{0},{1},{2},{3}",

myPBRclas1.i,myPBRclas1.j,myPBRclas1 .k,myPBRclas1.m);

myPBRclas1.func1(ref myPBRclas1.k,ref myPBRclas1.m);

Console.WriteLine(" III.i,j 's和k,m'是:{0},{1},{2},{3}",

myPBRclas1.i,myPBRclas1.j,myPBRclas1.k, myPBRclas1.m);


PassByRef01 placeHolderPassByRef01cl = new PassByRef01();


placeHolderPassByRef01cl.func3(myPBRclas1);

Console.WriteLine(" IV.i,j'和k,m'是:{0},{1},{2},{3}",

myPBRclas1.i,myPBRclas1.j,myPBRclas1.k,myPBRclas1.m);


placeHolderPassByRef01cl.func2(myPBRclas1.k,myPBRclas1.m);

Console.WriteLine(" V.i,j'和k,m'是:{0},{1},{2},{3}",

myPBRclas1.i,myPBRclas1.j,myPBRclas1.k,myPBRclas1.m);

Console.WriteLine(" VI.i,j'和k,m'是:{0 },{1},{2},{3}",

myPBRclas1.i,myPBRclas1.j,myPBRclas1.k,myPBRclas1.m);

Console.WriteLine(" reset values");

myPBRclas1。 k = 100;

myPBRclas1.m = 200;

Console.WriteLine(" 1。 k,m'是:{0},{1}",myPBRclas1.k,

myPBRclas1.m);

placeHolderPassByRef01cl.func4Swap(myPBRclas1);

Console.WriteLine(" 2.i,j'和k,m'是:{0},{1}",myPBRclas1.k,

myPBRclas1.m);

Console.WriteLine(现在使用''传统''交换');

placeHolderPassByRef01cl.func4TraditionalSwap(ref myPBRclas1);

Console.WriteLine(" 3.我,j'和k,m'是:{0},{1}",

myPBRclas1。 k,myPBRclas1.m);

Console.WriteLine(现在使用来自类内部的传统交换

(没有使用辅助类)");

myPBRclas1.swap1(ref myPBRclas1.k,ref myPBRclas1.m);

Console.WriteLine(" 4.i,j'和k,m'是:{0},{1}",

myPBRclas1.k,myPBRclas1.m);

}


}

}

/////////////////

使用系统;

使用System.Collections.Generic;

使用System.Linq;

使用System.Text;


命名空间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.WriteLine(" func1,k,m'是:{0},{1}",k,

m);

}

public void func2(int a,int b)

{

a = 1110000; //由于ref没有使用,这个赋值永远不会为k,b
b = 2220000;

Console.WriteLine(& ,k,m'是:{0},{1}",

k,m);

}


public void func3(PassByRef01 x)

{

xk = 66;

xm = 67;

Console.WriteLine(func3,k,m'里面是:{0},{1}",k,

m);

}


public void func4TraditionalSwap(ref PassByRef01 y)

{

int temp;

temp = yk;

yk = ym;

ym = temp;

}


public void func4Swap(PassByRef01 x)

{

int temp1,temp2;

temp1 = xk;

temp2 = xm;

xm = temp1;

xk = temp2;


Console.WriteLine(" func3,k,m'是:{0},{1}和

xk,xm为:{2},{3}",k,m,xk,xm);

}

public int i //无法通过ref传递物业

{

get {return _i; }

set {_i = value; }

}

public int j

{

get {return _j; }

set {_j = value; }

}

}


}

////////// /////////////输出


I.我,j'和k,m'是:10,11,1,2

里面的func2,k,m'是:1,2

II。我,j'和k,m'是:10,11,1,2
$ f $ b里面func1,k,m'是:1111,2222

三。我,j'和k,m'是:10,11,1111,2222

里面func3,k,m'是:1,2

IV。我,j'和k,m'是:10,11,66,67
$ f $ b里面func2,k,m'是:1,2

V.我,j'和k,m'是:10,11,66,67

VI。 i,j'和k,m'是:10,11,66,67

重置值

1. k,m'是: 100,200

里面func3,k,m'是:1,2和xk,xm是:200,100

2.我,j'是和k,m'是:200,100

现在使用''传统''交换

3.我,j'和k,m'' s是:100,200

现在使用来自课堂内部的传统交换(没有使用辅助类)

4.我,j'和k,m'' s是:200,100

按任意键继续。 。 。

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.Collections.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.WriteLine("I. i,j''s and k,m''s are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k,myPBRclas1.m);
myPBRclas1.func2(myPBRclas1.i, myPBRclas1.j);
Console.WriteLine("II. i,j''s and k,m''s are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
myPBRclas1.func1(ref myPBRclas1.k, ref myPBRclas1.m);
Console.WriteLine("III. i,j''s and k,m''s are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);

PassByRef01 placeHolderPassByRef01cl = new PassByRef01();

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

placeHolderPassByRef01cl.func2(myPBRclas1.k, myPBRclas1.m);
Console.WriteLine("V. i,j''s and k,m''s are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
Console.WriteLine("VI. i,j''s and k,m''s are: {0}, {1}, {2}, {3}",
myPBRclas1.i, myPBRclas1.j, myPBRclas1.k, myPBRclas1.m);
Console.WriteLine("reset values");
myPBRclas1.k = 100;
myPBRclas1.m = 200;
Console.WriteLine("1. k,m''s are: {0}, {1}", myPBRclas1.k,
myPBRclas1.m);
placeHolderPassByRef01cl.func4Swap(myPBRclas1);
Console.WriteLine("2. i,j''s and k,m''s are: {0}, {1}",myPBRclas1.k,
myPBRclas1.m);
Console.WriteLine("now use ''traditional'' swap");
placeHolderPassByRef01cl.func4TraditionalSwap(ref myPBRclas1);
Console.WriteLine("3. i,j''s and k,m''s are: {0}, {1}",
myPBRclas1.k, myPBRclas1.m);
Console.WriteLine("now use traditional swap from inside of class
(no helper class used)");
myPBRclas1.swap1(ref myPBRclas1.k, ref myPBRclas1.m);
Console.WriteLine("4. i,j''s and k,m''s are: {0}, {1}",
myPBRclas1.k, myPBRclas1.m);
}

}
}
/////////////////
using System;
using System.Collections.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.WriteLine("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.WriteLine("inside func2, k,m''s are: {0}, {1}",
k,m);
}

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

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

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

Console.WriteLine("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 . . .

推荐答案

你已经把它做死了;你还是挺的,相当不错。 Ref仅适用于参数 - 即x。


Marc
You''ve done this to death already; and you''re still quite, quite
wrong. Ref applies only to the arguments - i.e. "x".

Marc


10月15日,5:50 * am ,Marc Gravell< marc.grav ... @ gmail.comwrote:
On Oct 15, 5:50*am, Marc Gravell <marc.grav...@gmail.comwrote:

你已经做到了这个已经死了;你还是挺的,相当不错。 Ref仅适用于参数 - 即x。


Marc
You''ve done this to death already; and you''re still quite, quite
wrong. Ref applies only to the arguments - i.e. "x".

Marc



语义我的朋友。你明显错了。


这段代码的哪一部分你不明白?

public void func4Swap(PassByRef01 x)

{

int temp1,temp2;

temp1 = xk;

temp2 = xm;

xm = temp1;

xk = temp2;

Console.WriteLine(" func3,k,m'是:{0},{1}和

xk,xm是:{2},{3}",k,m,xk,xm);

}

它可以改变xm到xk这就是练习。


世界上所有的单词和所有的旋转都不会改变这个

verisimilitude。

RL

Semantics my friend. You are clearly wrong.

What part of this code don''t you understand?
public void func4Swap(PassByRef01 x)
{
int temp1, temp2;
temp1 = x.k;
temp2 = x.m;
x.m = temp1;
x.k = temp2;
Console.WriteLine("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


你没有使用ref传递限定符,但你传递了一个

引用,可以更改。


为了证明你是正确的,唯一的方法是编写通过的代码
此测试:


[TestMethod]

public void ProvePassByReferenceIsEsstentialIsALie()

{

int value1 = 1;

int value2 = 2;


交换(value1,value2);


Assert.AreEqual(2,value1);

Assert.AreEqual(1,value2);

}


你根本不允许更改测试源代码。你肯定不会这样做,我确定。


PS:说这是一个谎言。太荒谬了。在最坏的情况下,这将是一个错误,而不是

a谎言!


Pete

====
http://mrpmorris.blogspot.com
http://www.capableobjects.com
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 ProvePassByReferenceIsEsstentialIsALie()
{
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


这篇关于通过引用传递为“必要”交换暴露为谎言的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆