既然是一个小程序引发的思考,那么我们就先看看这个小程序,看看他有何神奇之处:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MyClass s = new MyClass();
s.val = 10;
int i = 20;
Console.WriteLine("s.val={0},i={1}",s.val,i);
MyMethod(s, i);
Console.WriteLine("s.val={0},i={1}", s.val, i);
Console.Read();
}
static void MyMethod(MyClass f1,int f2)
{
f1.val = f1.val + 5;
f2 = f2 + 5;
}
}
class MyClass
{
public int val = 20;
}
}
呵呵,大家看了以后可能会感觉这不是很简单的代码吗?有什么特别的地方吗?没有,真没有!但是我想问下大家这两次输出结果会有什么不同吗?分别是什么?有没有得出两次结果都是一样的?这个程序输出的结果是:
可能有些童鞋可能会问,不应该是一样的吗?为什么一个值变了,另外一个没有变呢?这是为什么呢?仔细的同学可能会发现static void MyMethod(MyClass f1,int f2)这个方法两个参数的类型不一样,f1属于引用类型,f2属于类型,是不是因为这个原因才导致两个变量经过同样的处理,s.val的值改变了,i的值却没有变。首先我们了解下什么是值类型,什么是引用类型。
值类型:值类型只需要一段单独的内存,用于存储实际的数据,他存在栈里面
引用类型:引用类型需要两段内存。
那这样说,像上面s对象,它是一个引用类型,那它应该存放在堆中,但是val又是个值类型,那它不是应该存放在栈中吗?
请记住,对于一个引用类型,其实例部分始终存放在堆里。既然val是对象s的一部分,那么它们都会被存放在堆里,无论它们是值类型还是引用类型。
栈:栈是一个内存数组,是一个LIFO(last-in first- out,后进先出)的数据结构,栈存储几种类型的数据。
亲爱的童鞋们,你们明白了吗?别看一点小程序,原来深挖可以得出那么多信息。其实也侧面说明了基础的重要性,童鞋们加油吧!