代码如下,问题是:Test应该算是引用类型吧,在method()中对t赋值的时候t = _t; 是不是仅仅是将 t 的指针指向了 _t ?按说 _t 是个局部变量,退出 method() 方法后 t 的指向就应该无效了,可是我用MessageBox.Show(t.str);测试发现 t 的指向仍然是有效的。t = _t; 和 t = new Test(_t); 有什么区别?
namespace test_AssignOfReferenceType
{
public partial class Form1 : Form
{
public Test t; public Form1 ()
{
InitializeComponent (); } private void toolStripButton1_Click (object sender , EventArgs e)
{
Test _t=new Test();
method (_t);
MessageBox.Show (t.str);
} public void method (Test _t)
{
//t是引用类型,测试对它的赋值是否需要用new
//这里看来不需要用new,直接=复制就可以
//那么和用new来赋值有什么区别?
t = _t;
//t = new Test(_t);
}
} public class Test
{
public string str;
public Test () { str = "xxx"; }
public Test (Test t) { str = t.str; }
}
}
namespace test_AssignOfReferenceType
{
public partial class Form1 : Form
{
public Test t; public Form1 ()
{
InitializeComponent (); } private void toolStripButton1_Click (object sender , EventArgs e)
{
Test _t=new Test();
method (_t);
MessageBox.Show (t.str);
} public void method (Test _t)
{
//t是引用类型,测试对它的赋值是否需要用new
//这里看来不需要用new,直接=复制就可以
//那么和用new来赋值有什么区别?
t = _t;
//t = new Test(_t);
}
} public class Test
{
public string str;
public Test () { str = "xxx"; }
public Test (Test t) { str = t.str; }
}
}
解决方案 »
- C#中所有的类和方法都是由.Net中的类库提供的吗?
- C#中如何调用.OCX中的函数?
- 水文中水位的问题
- dataadapter如何用update方法做表间数据备份
- 刚接触类,遇到一个比较肉的问题,请教大家
- 有没有办法按一个botton ,打开一个新窗口,而原页面不刷新?
- 对象实现IObjectReference接口,但无法解析该接口的全部依赖项。这可能是因为IObjectReference的两个实例具有彼此依赖性。
- 求助了,实在不知道怎么做?解决了一定会再多给分
- 请问向导窗口是如何作的?
- 怎样画一个椭圆的button?
- c#绘制一个图形,判断所绘图形是否在一定的坐标范围内
- 再次求助个时间问题,知道的朋友麻烦指点指点
如果是t = new Test(_t); 则是会在堆中重新生成一个对象
这么定义:
public Test(Test _t)
{
this = _t;
}
//则不会在堆中生成新对象,还是两个引用变量指向堆中同一个对象
这里有2个对象被创建:
new Test() 被创建在堆上
_t 是Test类型引用,按理说引用类型都被放在堆上,但不确定,因为离开函数就无效的,是交给垃圾回收来处理_t还是直接分配到栈上直接出栈回收。
t是成员变量
t指向new Test()这个对象,函数退出,_t被释放,但new Test()依然存在。
this 是read-only的,这个是错误的(抱歉)
new 一个对象的时候,会在栈内存中分配一个指针地址空间,存放堆内存中的一个地址值。这个值就是这个对象的首地址。
如果是=赋值的话,是不会开辟新的栈内存空间,而是把=右边的指针地址值赋给这个空间。
t = _t;
//t = new Test(_t);
这两种方式后,t的gethashcode方法值,默认该方法的值是当前对象的首地址值。
就明白有什么不同了。
test _t = new test();
中一个new test()创建的对象(对象1)在堆中创建并由 _t 引用。在
test t = new test();
中一个new test()创建的对象(对象2)在堆中创建并由 t 引用。当
t = _t
时t失去了对对象2的引用,开始引用对象1。(我个人估计对象2,已经是可销毁的了,不定什么时候就被垃圾收集了。)
public void method (Test _t)
{
//t是引用类型,测试对它的赋值是否需要用new
//这里看来不需要用new,直接=复制就可以
//那么和用new来赋值有什么区别?
t = _t;
}
按照 wuyazhe 兄的说法:
“_t 是Test类型引用,按理说引用类型都被放在堆上,但不确定,因为离开函数就无效的,是交给垃圾回收来处理_t还是直接分配到栈上直接出栈回收。”
我测试的结果,函数结束后,t的指向仍然有效,这是怎么回事呢?
t=_t; 之后 t 和 _t 指向堆上同一个对象
函数结束后 不管_t有没有效(当然这里_t失效了) 成员t一直有效(因为t是对象成员,生命期跟对象同存) t指向的对象也一直有效(直到t没效了,垃圾回收器回收)