日期:2014-05-20  浏览次数:20882 次

【oj每周推荐】谈谈.Net里的引用
上星期有个贴子string 赋值问题,从里面的回复来看,很多人都没有明白.Net里的“引用”,在此,对于那些还没搞清楚什么是值类型,什么是引用类型的人我不想再说些什么,只能建议他们多看看书。

首先问大家一个选择题,在写程序的时候,经常会碰到的一个异常就是:System.NullReferenceException ,也就是常见的“未将对象引用设置到对象的实例”,见可能见得多了,但可能还有很多人不明白这句话什么意思,那么,大家先来断断句,看看以下几个,你觉得哪个是正确的?
A、未将 对象 引用设置到 对象的 实例
B、未将 对象引用 设置到 对象的 实例
C、未将 对象 引用 设置到 对象的 实例

给出你的选择后,再看看下面这个例子:
MyClass mc1 = new MyClass();//MyClass为一个自定义的类
MyClass mc2 = mc1;
int i = 1;
int j = i;
以上四句代码在运行的时候,你觉得总共会创建几个对象?

大家都知道关键字ref和out 用在方法的参数前面,会导致参数通过引用来传递,那这里的“通过引用来传递”你是怎么理解的?


欢迎大家踊跃发言

------解决方案--------------------
B 喽
C# code

MyClass mc1 = new MyClass();    // 在托管堆上创建对象,并使mc1引用到该对象
MyClass mc2 = mc1;              // 将mc2引用到mc1引用的对象,此时MyClass.Equals(mc2, mc1)为true
int i = 1;                      // int 是值类型,在栈上存储。  i 为一个变量
int j = i;                      // 值类型 j 获取 值类型 i 的值的副本

------解决方案--------------------
引用楼主 ojlovecd 的帖子:
A、未将 对象 引用设置到 对象的 实例
B、未将 对象引用 设置到 对象的 实例
C、未将 对象 引用 设置到 对象的 实例

给出你的选择后,再看看下面这个例子:
MyClass mc1 = new MyClass();//MyClass为一个自定义的类
MyClass mc2 = mc1;
int i = 1;
int j = i;
以上四句代码在运行的时候,你觉得总共会创建几个对象?

大家都知道关键字ref和out 用在方法的参数前面,会导致参数通过引用来传递,那这里的“通过引用来传递”你是怎么理解的?


------解决方案--------------------
不过这里再补充一点,说到String 类型,它还是有点特殊的.
首先,String和string都一样,string最终会翻译成.NET结构中的Sysem.String的。
其次,String是引用类型。但如下的代码:
string a="hello";
string b=a;
b+=",world.";
此时,a的值仍然是"hello",b的值变成了"hello,world.".这里反而表现成了值类型的特性。这是运算符重载的结果。有兴趣的可以找书看看。

------解决方案--------------------
在C++中
引用和指针就是很好的说法

ref、out的引用,其实就是C++中的引用(即别名)
而不加ref out 引用类型就会在复制一个指针,而这个指针只是指向这个地址。
值类型就会复制一个值,而不是原先的对象
在此就回答下oj的第二个问题
MyClass mc1 = new MyClass();//MyClass为一个自定义的类
MyClass mc2 = mc1;
int i = 1;
int j = i; 

第一句创建了一个对象(这个堆)
第二句则没有
第三句创建了一个值类型(这个堆栈)
因为这个原因,第四句其实在堆栈里重新分配了内存空间

oj的第一题有点咬文嚼字,但是却能说明一个问题
我给出的答案和wartim兄是一样的。B。
用指针来解释应该更容易理解点吧 
呵呵
------解决方案--------------------
C# code

object o = new object();

------解决方案--------------------
探讨
C# code
object o = new object();




new object() 在托管堆上创建了一个匿名对象.

将其 '引用' 赋值给了 object 类型的引用 o,

对象住在 托管堆里, o 不是那个对象本身,

如图:
------------------------------------
| 堆栈 | 托管堆 |
| | |
| o --->|-->new 创建的匿名对象 |
------------------------------------

o 好比就是一根…

------解决方案--------------------
C# code

MyClass mc1 = new MyClass();//MyClass为一个自定义的类
MyClass mc2 = mc1;
int i = 1;
int j = i;

------解决方案--------------------
探讨
C# codeobjecto=newobject();

new object() 在托管堆上创建了一个匿名对象.

将其 '引用' 赋值给了 object 类型的引用 o,

对象住在 托管堆里, o 不是那个对象本身,

如图:
------------------------------------
|  堆栈    |    托管堆            |
|          |                      |
|    o  --->|-->new 创建的匿名对象 |