C#与.NET程序员面试宝典 3.1.4 面试题23:有几种方法可以判断值类型和引用类型

值类型和引用类型都是.NET预定义的数据类型,虽然它们都继承自System.Object,但这两种类型各有特点。这道面试题在技术笔试中,是出现概率最高的面试题之一,读者一定要深入理解值类型和引用类型。

 

【出现频率】★★★★★

 

【关键考点】

值类型和引用类型的基本概念

值类型和引用类型的赋值

值类型和引用类型的继承结构

值类型和引用类型的内存分配

 

【考题分析】

.NET的类型可以分为值类型和引用类型。值类型(Value Type)实例通常分配在线程的堆栈上,并且不包含任何指向实例数据的指针。引用类型(Reference Type)类型实例分配在托管堆上,变量保存了实例数据的内存引用。有以下3种方法可以判断值类型和引用类型:

 

(1)值类型和引用类型赋值区别

值类型变量赋值只是进行数据复制,创建一个同值新对象,而引用类型变量的赋值仅仅是把对象的引用的指针赋值给变量,使得变量引用与对象共享同一内存地址。

下面来看一段简单的示例,首先为了演示的方便在这只建立一个引用类型和一个值类型。

using System;

namespace MyConsole

{

    class ValueTypeAndRefType

    {

        class SomeRef                                                                    //定义一个引用类型

        {

            public int x;

        }

        struct SomeVal                                                                    //定义一个值类型

        {

            public int x;

        }   

        static void Main(string[] args)

        {

            SomeRef Reference1 = new SomeRef();              //分配在托管堆上

            SomeVal Value1 = new SomeVal();                               //分配在堆栈上

            Reference1.x = 3;                                                       //解析指针

            Value1.x = 3;                                                                       //在堆栈上修改

            Console.WriteLine("引用类型: Reference1=" + Reference1.x);  //显示为“3”

            Console.WriteLine("值类型: Value1=" + Value1.x);    //显示为“3”

            SomeRef Reference2 = Reference1;                               //仅拷贝引用(指针)

            SomeVal Value2 = Value1;                                       //先在堆栈上分配,然后拷贝成员

            Reference1.x = 8;                                    //改变了Reference1.x和Reference2.x

            Value1.x = 7;                                              //改变了Value1.x,没有改变Value2.x

            Console.WriteLine("引用类型: Reference1=" + Reference1.x); //输出信息

            Console.WriteLine("引用类型: Reference2=" + Reference2.x);

            Console.WriteLine("值类型: Value1=" + Value1.x);

            Console.WriteLine("值类型: Value2=" + Value2.x);  

            Console.ReadLine();

        }       

    }

}

 

(2)继承结构的区别

引用类型一般都有继承性。但由于值类型是密封的(sealed),因此值类型不能作为其他任何类型的基类,但是可以单继承或者多继承接口。另外一个区别是值类型都继承System.ValueType类,而引用类型则不会继承System.ValueType类。

 

(3) 内存分配的区别

值类型和引用类型在内存的分配位置上也有区别。值类型通常被分配在栈上,它的变量直接包含变量的实例,使用效率相对比较高。而引用类型分配在托管堆上,引用类型的变量通常包含一个指向实例的指针,变量通过该指针来引用实例。

 

注意:GC(垃圾回收,Gabage Collection)控制引用类型的内存回收,但不控制值类型的内存。在作用域结束时,值类型会自行释放,由于减少了托管堆的压力,因此在性能上具有一定的优势。

 

【答案】

值类型数据是在栈中分配空间的,是在数据定义的时候就按照所需要的大小分配空间,所以在数据的存取时效率比较高,而引用类型是在堆中分配的,类和结构都属于引用类型。通常程序员自己定义的数据类型大部分都是引用类型。当然最简单也最常用的一个方法是看这个类型是否继承自System.ValueType。继承自System.ValueType的类型是值类型反之则是引用类型。

posted @ 2010-11-01 17:17  面试宝典  阅读(1641)  评论(2编辑  收藏  举报