Value Type And Reference Type

来源:互联网 发布:js形参和实参不匹配 编辑:程序博客网 时间:2024/04/29 16:16

值类型和引用类型
在解释C#数据类型之前、理解C#的两类数据类型之间的区别很重要
1.值类型(Value types)
2.引用类型(Reference types)

下一部分我们关注值类型和引用类型在句法上的区别,理论上,值类型和引用类型的区别是值类型直接存储自身的值,引用类型存储一个自身值的引用,C#中值类型主要是一些基础类型(如 整形,浮点,非指针(pointers )或引用),在VB或C++中,引用类型是和VB中引用类型,C++中指针类型是一样的.这些类型在内存中时存在不同的地方,值类型存储在被称之为栈(stack)的地方,引用类型存储在被叫做堆(heap)的地方,由于不同的分配的情况下,很好意识一个类型是值类型或是引用类型这点很重要,For example,int 是值类型,
下面的例子的导致结果是在内存中有两个位置存储值20
// i and j are both of type int
i = 20;
j = i;

然而,考虑到下面的代码,在这段代码中,假设你已定义一个Vector类,它含有一个int类型的成员Value
Vector x, y;
x = new Vector();
x.Value = 30; // Value is a field defined in Vector class
y = x;
Console.WriteLine(y.Value);
y.Value = 50;
Console.WriteLine(x.Value);

重点是在运行这段代码后,这里只有一个Vector对象,x,y同是指向内存(memory )中同一个位置[存储Vector],因为x,y都是一个引用类型的变量,申明每一个变量就能简单的存储一个引用—这就不需要实例化一个已知道类型的对象,这和C++中申明指针或VB中对象引用是一样的,不论在那种情况一个对象都不会被创建的,但为了创建一个对象,你得使用New关键字,如上所示,因为x,y同指向一个对象,改变x会影响到y,反过来也一样,因此,上断代码会显示30和50.如果一个变量是一个引用,在它没有指向任何对象的时候,我们可以设置它值为null:

y=null;

如果一个引用被设置为null,那很清楚的是不可能调用任何和它有直接关系非静态的成员函数或字段,如果你这样做运行时抛出异常,C++中,开发人员可以选择是否一个给定值被访问直接或通过一个指针,VB相对比较严格,就拿COM对象,它是引用类型,同时简单类型一直是引用类型,C#在这点和VB是相似的,值类型和引用类型的判断是由其数据类型判断的,所以,int, for exampl,一直是值类型,你不可能给int类型赋值一个引用类型,在C#中,基础数据类型如布尔和long类型都是值类型,这意味着如果你定义
一个bool变量,并给它附一个其他bool变量的值,那你会发现在内存中,有两个分开的bool值,过后,你改变原有的bool变量的值,第二个bool的值不会改变,这些类型的赋值只是拷贝自身的值.
相反,C#大多数复杂的数据类型,包含用户自定义类都是引用类型,他们都分配在堆中,可调用,可访问,有生命周期,公共语言运行时(CLR)的实现一个复杂的算法来跟踪该引用变量仍可达,并已被孤立。每隔一段时间(Periodically),CLR将摧毁孤立的对象和返回内存中被占用的资源给操作系统。这是由垃圾收集器来做。C#中已经设计了这种方式,因为高性能最好保持原始类型的服务(如int和布尔)值类型和较大的类型,包含许多领域(通常是带类的情况下)引用类型,如果你想定义自己的类型为值类型,你应该定义它作为一个结构。

下面是个例子:看看它们的区别吧再见

   class A    {        public int Num        {            get;            set;        }        public override string ToString()        {            return "A";        }    }     static void Main(string[] args)        {            //Value Type            int i = 5;            int j = 0;            j = i;            Console.WriteLine("i:{0},j:{1}",i,j);            j = 9;            Console.WriteLine("i:{0},j:{1}", i,j);            //Reference Type            A a, b;             a = new A();            a.Num = 9;            b = a;            Console.WriteLine("a.Num:{0},b.Num:{1}", a.Num, b.Num);            b.Num = 50;            Console.WriteLine("a.Num:{0},b.Num:{1}", a.Num, b.Num);            //Reference Type            string sa, sb;            sa = "You";            sb = sa;            Console.WriteLine("sa.{0},sb.{1}",sa,sb);            sb = "I";            Console.WriteLine("sa.{0},sb.{1}", sa, sb);            Console.ReadKey();        }


 推荐博客:RyanDoc数据字典 For SqlServer版            RyanCoder代码生成器 For SqlServer版