C# 中的引用类型和值类型

来源:互联网 发布:网络对于大学生的影响 编辑:程序博客网 时间:2024/06/09 22:28

C#中所有的类都是引用类型,大部分基本类型是值类型,基本类型中也有一些是引用类型,包括string、object。数组也是隐式的引用类型。

那么什么是值类型,什么是引用类型?主要区别包括:1在内存中的位置不同,2使用方式不同。

1 内存中的位置不同

值类型是在系统的堆栈中分配空间,引用类型是在系统的堆中分配空间。

2 使用方式

public class MyClass{    public int val;};public struct MyStruct{    public int val;};...static void Main(string[] args){    MyClass c1 = new MyClass();    MyClass c2 = c1;    MyStruct s1 = new MyStruct;    MyStruct s2 = s1;    c1.val = 10;    c2.val = 20;    s1.val = 30;    s2.val = 40;    Console.WriteLine("{0} {1} {2} {3}", c1.val, c2.val, s1.val, s2.val);}
上面代码的输出是20,20,30,40。

也就是,c1,c2是指向同一个类,对任何一个变量的修改都会影响到另外一个。

这个操作和C++有着非常大的区别。

在C++中,这个操作调用的是类重载的赋值操作符。如果没有自己定义,编译器会为每个类定义一个默认的赋值操作符。默认操作符的工作是简单的把每个类成员复制给左值的每个对应的类成员。也就是说,它的前提是,赋值操作符的左值和右值是不同的对象的实体。在C++中,如果类的成员中没有指针,那么直接用编译器提供的赋值操作符是安全的。

但在C#中,对于引用类型,赋值操作符就是把右值的引用复制给左值。那么结果就是左值成了和右值一样的引用。如果左值本来是另外一个对象的引用,那么这个对象就没丢弃,如果它的引用计数为0,那么就只能等待垃圾回收程序来回收它占用的内存。

所以,如果函数的形参是一个引用类型,函数都会修改这个引用类型所指向的值,不管它有没有用ref关键字。如果没有用ref关键字修饰引用类型,函数可以修改该应用类型指向的值,但不会修改引用类型本身的指向!!!

另外,new后面的类型名称似乎都必须加"()"。