值类型
- 值类型存储在栈中
- 分配的空间大小因类型的不同而不同
引用类型
- 引用类型在栈中分配的空间是相同的,不同的是在堆中分配的空间
- 赋值是的变化 ; Student s = new Student(); s = new Student();
C#的值类型包括:结构体(数值类型,bool型,用户定义的结构体),枚举,可空类型。
C#的引用类型包括:数组,用户定义的类、接口、委托,object,字符串。
数组的元素,不管是引用类型还是值类型,都存储在托管堆上。
引用类型在栈中存储一个引用,其实际的存储位置位于托管堆。为了方便,本文简称引用类型部署在托管推上。
值类型总是分配在它声明的地方:作为字段时,跟随其所属的变量(实例)存储;作为局部变量时,存储在栈上。
值类型在内存管理方面具有更好的效率,并且不支持多态,适合用作存储数据的载体;引用类型支持多态,适合用于定义应用程序的行为。
值类型:
单元直接存放“有效值”
如:
int a=3;
则a内存单元就放的是3
引用类型:
单元放的是另外一个对象的引用(地址)
如:
Form form1=new Form();
就是说,在内存中开辟了一个对象new Form(),form1内存单元存放的是那个对象的地址,并非对象本身
3 引用类型和值类型实例
static void ShowDouble(int val)
{
val *= 2;
Console.WriteLine("val double = {0}", val);
}
int myNumber = 5;
Console.WriteLine("myNumber = {0}",myNumber);
ShowDouble(myNumber);
Console.WriteLine("myNumber = {0}",myNumber);
输出的结果为:
myNumber = 5
myNumber = 10
myNumber = 5
把myNumber作为一个参数,调用ShowDouble()并不影响Main()中myNumber返回值的函数。
但是如果我们把上面的代码修改成如下:
static void ShowDouble(ref int val)
{
val *= 2;
Console.WriteLine("val double = {0}", val);
}
int myNumber = 5;
Console.WriteLine("myNumber = {0}",myNumber);
ShowDouble(ref myNumber);
Console.WriteLine("myNumber = {0}",myNumber);
输出结果为:
myNumber = 5
myNumber = 10
myNumber = 10
这次myNumber中的值被ShowDouble()修改了。
同样的除了ref关键字以外还有一个out关键字,在作为参数使用的时候,out参数必须看做是还未赋值,实例:
static int MaxValue(int[] intArray,out int maxIndex)
{
int maxValue = intArray[0];
maxIndex = 0;
for(int i = 0; i < intArray.Length; i ++)
{
if(maxValue < intArray[i])
{
maxValue = intArray[i];
maxIndex = i;
}
}
return maxValue;
}
int[] myArray = { 1,2,3,4,5,6,7,8};
int maxIndex;
Console.WriteLine("The maximum value in myArray is {0}",MaxValue(myArray,out maxIndex));
Console.WriteLine("The first occurrence of this value is at element {0}",maxIndex + 1);
输出结果:
The maximum value in myArray is 8
The first occurrence of this value is at element 8