再谈看似简单的ref,送分题,看看大家的语言表达

lonyjianhui 2010-11-13 11:42:36
前几天在别人的帖子跟尾,发现很多人都属于会用不会说的类型(我也属于这类),今天又跟同事讨论了几个小时虽然很乱,但得益良多,大家尽量不要用指针说话,我当初放弃C就是因为指针0.0,也别用全理论说,听多了厌,最好用我代码的例子,下面先看看我在别人帖子跟尾的代码:

问题:1.result到底是多少?(相信大家都会做)
2.如何分析?最好用对比分析。(相信也会有少部分人会说)

参考知识:1.ref按引用传递,int为值类型,string为引用类型;
2.http://msdn.microsoft.com/zh-cn/library/14akc2c7(VS.80).aspx
http://blog.csdn.net/cctt_1/archive/2007/08/23/1755650.aspx

private void button1_Click(object sender, EventArgs e)
{
string x = "1";
string y = "2";
string x0 = "1";
string y0 = "2";
int x1 = 1;
int y1 = 2;
int x2 = 1;
int y2 = 2;

XXX(ref x,ref y);
XXX(x0, y0);
XXX(ref x1,ref y1);
XXX(x2, y2);

string result="x:"+x + " y:" + y+"x0:"+x0+" y0:"+y0+"x1:"+ x1 + " y1:" + y1+"x2:"+x2+" y2:"+y2;
MessageBox.Show(result);
}

void XXX(string x,string y)
{
string t = null;
t = x;
x = y;
y = t;
}
void XXX(ref string x, ref string y)
{
string t = null;
t = x;
x = y;
y = t;
}
void XXX(int x,int y)
{
int t = 0;
t = x;
x = y;
y = t;
}
void XXX(ref int x, ref int y)
{
int t = 0;
t = x;
x = y;
y = t;
}
...全文
343 39 打赏 收藏 转发到动态 举报
写回复
用AI写文章
39 条回复
切换为时间正序
请发表友善的回复…
发表回复
兔子-顾问 2010-11-16
  • 打赏
  • 举报
回复
不是,是你对c#、c++以及内存管理的知识不足,讨论时候无法说服和c#无关。
兔子-顾问 2010-11-15
  • 打赏
  • 举报
回复
楼主不要和同事争,听你们懂c++同事给你的解释就好。
lonyjianhui 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 peng2739956 的回复:]
只需要看 含有ref关键字的方法 其他的方法不看因为不会改变值 所以x=2,y=1,t=1第一个ref第2个t=1,x=2,y=0、、其他的x,y值都不变
[/Quote]
很好,不过,那句“只需要看”就有点问题啦,当然对于我上面给出的具体代码没有问题,但是,你再看看:

static void Main()
{
//Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
List<string> lst = new List<string>();
lst.Add("1");
lst.Add("2");
Console.WriteLine(string.Format("First:{0},Second:{1}",lst[0],lst[1]));
XXX(lst);
Console.WriteLine(string.Format("First:{0},Second:{1}", lst[0], lst[1]));
}
public static void XXX(List<string> lst)
{
lst[0] = "5";
lst[1] = "6";
}
lonyjianhui 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 microtry 的回复:]
引用楼主 lonyjianhui 的回复:
参考知识:1.ref按引用传递,int为值类型,string为引用类型;

1.看看自己的代码,你都能知道string是值类型

C# code
string x = "1";


C#的string :当你当值类型用的时候(比如逻辑比较==),它呈现值类型的特性,
当你当作对象使用的时候,它就呈现String类型的特性,
……
[/Quote]

感谢,指教了
lonyjianhui 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 27 楼 sp1234 的回复:]
lz在“知识”第一个之中的“按引用传递”实际就是.net迷惑人的地方。

.net中如果你在传递参数是定义int或者ref int,它们如何体现“按引用传递”?这就逼着人去往c++的概念上去套。

其实.net不论你写int还是ref int,都是传值的。对于引用类型也一样,不论写还是不写ref,都是传引用对象(这个引用对象作为值)的。其实没有区别。这才能解释为什么.net中ref总是比不……
[/Quote]

大哥,这才叫不留嘛,很好啊。我们几个同事昨天去吃饭的时候也讨论得很激烈,因为大家用的语言都不同,根本就把语言放到一边去,直接从底层说起了,不过说到c#,真的很佩服你的功底啊,我在书上还没见过这种描述呢,不知道有没有参考资料看下。顺便,能帮我解析一下下面两个方法吗?花一点点时间看看嘛,谢啦哈

void XXX(ref int x, ref int y)
{
int t = 0;
t = x;
x = y;
y = t;
}
void XXX(string x,string y)
{
string t = null;
t = x;
x = y;
y = t;
}
lonyjianhui 2010-11-15
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 wuyazhe 的回复:]
楼主不要和同事争,听你们懂c++同事给你的解释就好。
[/Quote]
0.0被你说中了,他们几个c++的说得别人不能不服,我总是感觉用c#描述说服力不够,不知道是不是因为c#封装了太多的东西。。
peng2739956 2010-11-14
  • 打赏
  • 举报
回复
只需要看 含有ref关键字的方法 其他的方法不看因为不会改变值 所以x=2,y=1,t=1第一个ref第2个t=1,x=2,y=0、、其他的x,y值都不变
兔子-顾问 2010-11-13
  • 打赏
  • 举报
回复
ref简单说就是表示修饰的形参是调用处的一个引用,如果传递的是引用类型,引用类型本就是引用某个对象的,ref修饰的就是这个引用的引用。自己记得就好,虽然新手才会有的疑惑,但尽量少这么用,前几天有人发贴说了滥用ref到后期维护的痛苦。我以前一个项目,几万行,用ref的地方的确是少之又少。很多地方都可以不用这么做的。做例子理解就好,公司代码中慎用。
colorall 2010-11-13
  • 打赏
  • 举报
回复
XXX(ref x,ref y);//1,2->2,1
XXX(x0, y0);//1,2->1,2
XXX(ref x1,ref y1);//1,2->2,1
XXX(x2, y2);//1,2->1,2
我是不会说的类型,组织组织语言再说。
dafei198607 2010-11-13
  • 打赏
  • 举报
回复
挺不错,也是说不清楚,嘿嘿,楼主总结的挺好,挺起
lonyjianhui 2010-11-13
  • 打赏
  • 举报
回复
大家可别说因为传递的是值类型、引用类型。。。。所以。。。这说都会
可又有多少人会为什么传递的是值类型,结果就是这样等等呢
wwmm5201348 2010-11-13
  • 打赏
  • 举报
回复
只知道用ref传的是内存地址。具体的不熟悉,没用过ref的飘过
lonyjianhui 2010-11-13
  • 打赏
  • 举报
回复
我来坐沙发
1.答案:我是LZ就不说了,留给下面;
2.分析:引用类型(string)在栈中存储一个引用,其实际的存储位置位于托管堆。值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量存储;作为局部变量时,存储在栈上。
由于传string x,y时,传递的是在栈中某两个位置的值(该值指示x,y的值存储在托管堆上的位置),而传递int x2,y2时,传递的是......下面的留给楼下答了,答得好的话适当加分哈。
缪军 2010-11-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 lonyjianhui 的回复:]
参考知识:1.ref按引用传递,int为值类型,string为引用类型;
[/Quote]
1.看看自己的代码,你都能知道string是值类型
string x = "1";

C#的string :当你当值类型用的时候(比如逻辑比较==),它呈现值类型的特性,
当你当作对象使用的时候,它就呈现String类型的特性,
所以,实际代码中,大多数是拿string当值使用 ,参见:
http://msdn.microsoft.com/zh-cn/library/362314fe.aspx

2.C#很多东西貌似C++,但是都是虚拟的,就好象ref,就是这么一个写法,MSDN已经说的清清楚楚的了,
这跟C++概念上的传值还是传址没什么关系:
再次把MSDN原文的关键字摘录出来:
其效果是,在方法中对参数所做的任何更改都将反映在该变量中。
若要使用 ref 参数,则必须显式使用 ref 关键字,
很明显,原文的描述尽量撇清容易联想到C++的影响
hukui161 2010-11-13
  • 打赏
  • 举报
回复
引用可以当着别名理解。
烈火蜓蜻 2010-11-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 lonyjianhui 的回复:]
前几天在别人的帖子跟尾,发现很多人都属于会用不会说的类型(我也属于这类),今天又跟同事讨论了几个小时虽然很乱,但得益良多,大家尽量不要用指针说话,我当初放弃C就是因为指针0.0,也别用全理论说,听多了厌,最好用我代码的例子,下面先看看我在别人帖子跟尾的代码:

问题:1.result到底是多少?(相信大家都会做)
2.如何分析?最好用对比分析。(相信也会有少部分人会说)

参考知识:……
[/Quote]

当你想一个函数返回多个参数的时候,又不想多定义一个类型,那你怎么办?
sxldfang 2010-11-13
  • 打赏
  • 举报
回复
变量x,不管是何类型,在内存中都有自己的存储空间。对值类型,其存放的就是值本身;而对引用类型,变量存放的是值的地址,值却另外占有存储空间。
sxldfang 2010-11-13
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 bloodish 的回复:]
引用 23 楼 sxldfang 的回复:
名字不同,实际是一个东西……


这样理解不正确,只能说两个引用指向的内存地址是相同的,引用本身不是同一个.
站到内存的高度去看问题,不要被语法迷惑了.
[/Quote]

其实每个人都有自己的理解方法,而我就觉得我的是最本质的东西,O(∩_∩)O哈哈~
  • 打赏
  • 举报
回复
lz在“知识”第一个之中的“按引用传递”实际就是.net迷惑人的地方。

.net中如果你在传递参数是定义int或者ref int,它们如何体现“按引用传递”?这就逼着人去往c++的概念上去套。

其实.net不论你写int还是ref int,都是传值的。对于引用类型也一样,不论写还是不写ref,都是传引用对象(这个引用对象作为值)的。其实没有区别。这才能解释为什么.net中ref总是比不写它要效率低的原因。

它们的区别只是在调用结束堆栈pop的时候,要不要把结果保留还是直接丢弃。
sxldfang 2010-11-13
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 sp1234 的回复:]
net它总是把对象的引用压入堆栈,不管你写还是不写ref都一样。[/Quote]

我觉得和C++的概念是一样的!

对一变量x来说,不用ref压入的是变量的值;用ref,压入的是变量的地址。

不管是值类型还是引用类型,都是通用的。只不过值类型存的是值,而引用类型存放的是地址。
加载更多回复(19)

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧