数据类型(1) - 值类型和引用类型

和javascript等脚本语言不同,C#基本上可以说是强类型的编程语言。这意味着,任何变量在编译时(而不是运行时)就必须要有一个类型。直到c#4.0,引入了动态类型为止。c#的弱类型体现在其类型object中。任何变量都可以是object类型的,也就是说他们在编译时没有类型,肯定能通过编译。但错误将会在运行时才发生。

强类型的好处有很多,例如可以保证类型安全(否则将会发生运行时错误),可以享受IDE带来的智能提示等,不容易出错(出错可以在编译的时候就知道)。c#有很多数据类型,而他们可以分为两类:ValueType(值类型)和ReferenceType(引用类型)。前者包括int, double, long等等那些数值类型,bool,结构体和枚举。后者则比较抽象,包括类,接口,委托,数组,字符串等。搞清楚两大类数据类型的特性非常重要,这也是一个面试基础题目:

  1. 所有值类型的默认值都是0,所有引用类型默认值都是Null。这可以反过来作为我们对某种类型究竟是值类型还是引用类型的判断方法。例如字符串是一个容易令人混淆的类型,但只要想到他的默认值是null不是0,就很容易的可以判定它是属于引用类型了。另外,这也是系统自带的构造函数的行为,即为所有值类型设置初始值0,引用类型则是null。
  2. 值类型初始化分配在栈上(在栈上拥有一块空间,其大小根据值类型的大小而定),且拥有清晰的生命周期,一旦使用完毕立即被回收。引用类型初始化分配则比较复杂,在堆上分配引用类型,其占用空间大小由引用类型本身的大小决定,在栈上加入一个引用,其为一个类似指针的东东,指向堆上那块空间。使用完毕要等垃圾收集器回收,且回收时候不确定。注意,这句话实在是太重要了,所以我再重复一遍,值类型初始化分配在栈上,引用类型初始化分配在堆上,其占用空间大小由引用类型本身的大小决定,另外还要在栈上加入一个引用,其为一个类似指针的东东,指向堆上那块空间。如果初始化没有赋值,则只会在堆上分配一块空间,而没有指针。
  3. “初始化”的学名是使用new关键字。如果不加参数的话,将调用数据类型自己的默认构造函数。无论是值类型还是引用类型都可以。如果还有其他构造函数,则视你传入的变量的数量和类型,系统决定调用哪个构造函4 数。例如你完全可以int a = new int(),这等效于int a=0,因为new调用类Int32的默认构造函数,而其将值设置为0。值得注意的是,值类型的默认构造函数是不能被覆盖的,你只能定义有参数的构造函数。
  4. 所有的值类型都不支持继承,而引用类型可以(如果不是密封类)。
  5. 值类型可以包含引用类型作为其属性,反之亦然。值类型和引用类型都可以实现字段,属性,方法,接口和事件。
  6. 为值类型赋值时,是进行简单的复制。为引用类型赋值时,是改变指针的指向。例如

   int i=0; int j=i;

  此时如果改变i的值,j的值将不受影响。但如果i是一个引用类型,则j=i意味着i和j的指针指向相同的地方。所以改变任何一个的值,另一个也会受到影响。这种行为称之为浅复制,即仅仅在栈上复制一个引用,而指针则仍然指向相同的地方(即堆上仍然是只有一个对象但是现在两个引用指向它)。如果要在堆上开辟一个新的对象,则要使用深复制,其方法为实现ICloneable接口。引用类型浅复制的行为是默认的,即使是一个较复杂的值类型,其中包含引用类型(例如你可以写一个包含类的结构体),其行为也是一样。



 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             rectangle a = new rectangle("info", 10, 20);
 6             rectangle b = a;
 7             a._chang = 999;
 8             a._recinfo.infostring = "new info";
 9
10             Console.WriteLine(string.Format("A: chang is {0} and kuan is {1}, info: {2}", a._chang, a._kuan, a._recinfo.infostring));
11             Console.WriteLine(string.Format("B: chang is {0} and kuan is {1}, info: {2}", b._chang, b._kuan, b._recinfo.infostring));
12             Console.ReadKey();
13         }
14     }
15
16     struct rectangle
17     {
18         public shapeinfo _recinfo;
19         public double _chang;
20         public double _kuan;
21
22         public rectangle(string recinfo, double chang, double kuan)
23         {
24             _recinfo = new shapeinfo(recinfo);
25             _chang = chang;
26             _kuan = kuan;
27         }
28     }
29
30     class shapeinfo
31     {
32         public string infostring;
33
34         public shapeinfo(string s)
35         {
36             infostring = s;
37         }

运行代码可以看到两个结构体的shapeinfo的值都变了,而其属于值类型的那两个double则是互相不受影响。

时间: 2024-10-10 01:18:22

数据类型(1) - 值类型和引用类型的相关文章

JavaScript基本数据类型及值类型和引用类型

在JavaScript中四种基本的数据类型:数值(整数和实数).字符串型(用“”号或‘'括起来的字符或数值).布尔型(使True或 False表示)和空值.在JavaScript的基本类型中的数据可以是常量,也可以变量.由于JavaScript采用弱类型的形式,因而一个数据的 变量或常量不必首先作声明,而是在使用或赋值时确定其数据的类型的.当然也可以先声明该数据的类型,它是通过在赋值时自动说明其数据类型的. javascript中的变量 javascript中的变量只是一个占位符,前言已经说过了

堆栈,堆,值类型,引用类型,装箱和拆箱

当你声明一个变量时内存中都发生了什么? 当你在一个.Net应用程序中声明一个变量时,首先要分配一些内存快到RAM,它包括三样东西,第一个是变量名,第二个是变量的数据类型,最后一个是变量的值. 这只是一个很简单的解释,根据变量的数据类型不同,有两种内存分配类型:堆栈内存和堆内存. 图 2 声明变量后的内存结构 堆栈(stack)和堆(heap) 为了帮助理解堆栈和堆,让我们了解下面的代码内部究竟发生了什么. public void Method1() { // Line 1 int i=4; //

java和c#值类型和引用类型

java数据类型分为基本数据类型和引用类型 基本数据类型:int  float  double  bool  char byte 引用数据类型:string  array  class interface  list 为什么区分是基本数据类型还是引用数据类型? 基本数据类型和引用数据类型在内存的存储方式是不同的,这会导致代码的运行速度不同.基本数据类型数据值直接存储在内存栈上:引用数据类型数据值放在内存堆上,在栈中存放数据值的地址(引用),以访问数据值. 那么栈和堆究竟哪个更好?栈的存取速度优于

Swift - 值类型和引用类型的区别

在Swift中数据类型分为值类型和引用类型,只有类是引用类型,其他类型都是值类型.那么值类型和引用类型有什么区别呢?值类型是在赋值或给函数传递参数时创建一个副本,把副本传递过去,在函数的调用过程中不会影响原始数据.而引用类型是在赋值或给函数传递参数时把本身引用传递过去,在函数调用过程中会影响原始数据.值类型参数不能直接以引用类型传递,而是不仅需要将值类型参数声明为inout而且要在使用实例前加上&符号. 原文地址:https://www.cnblogs.com/54tester/p/107775

javascript基本数据类型与值类型引用类型说明

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文主要讲了javascript中的基本数据类型,以及值类型和引用类型的区别与使用 一.基本数据类型 在javascript中申明变量使用的关键字都是var,这点与其他的编程语言不尽相同,但是javascript亦含有五种基本的数据类型(也可以说是简单数据类型),它们分别是:Undefined,Null,Boolean,Number和String.还含有一种复杂数据类型-Object.

定义类+类实例化+属性+构造函数+匿名类型var+堆与栈+GC回收机制+值类型与引用类型

为了让编程更加清晰,把程序中的功能进行模块化划分,每个模块提供特定的功能,而且每个模块都是孤立的,这种模块化编程提供了非常大的多样性,大大增加了重用代码的机会. 面向对象编程也叫做OOP编程 简单来说面向对象编程就是结构化编程,对程序中的变量结构划分,让编程更清晰. 类的概念: 类实际上是创建对象的模板,每个对象都包含数据,并提供了处理和访问数据的方法. 类定义了类的每个对象(称为实例)可以包含什么数据和功能. 类中的数据和函数称为类的成员:数据成员        函数成员 数据成员: 数据成员

Java值类型和引用类型

[定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变.值类型表示复制一个当前变量传给方法, 当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.通俗说法: 值类型就是现金,要用直接用:引用类型是存折,要用还得先去银行取现.----(摘自网上) [值类型] 也就是基本数据类型 基本数据类型常被称为四类八种 四类: 1,整型 2,浮点型 3,字符型4,逻辑型 八种: 1,整型3种 by

java 值类型和引用类型的区别

1. Java中值类型和引用类型的不同? [定义] 引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值, 那么调用这个方法是传入的变量的值也将改变.值类型表示复制一个当前变量传给方法, 当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.通俗说法: 值类型就是现金,要用直接用:引用类型是存折,要用还得先去银行取现.----(摘自网上) [值类型] 也就是基本数据类型 基本数据类型常被称为四类八种 四类: 1,整型 2,浮点型 3,字

C#中值类型和引用类型

本文将介绍C#类型系统中的值类型和引用类型,以及两者之间的一些区别.同时,还会介绍一下装箱和拆箱操作. 值类型和引用类型 首先,我们看看在C#中哪些类型是值类型,哪些类型是引用类型. 值类型: 基础数据类型(string类型除外):包括整型.浮点型.十进制型.布尔型. 整型(sbyte.byte.char.short.ushort.int.uint.long.ulong ) 浮点型(float 和 double ) 十进制型(decimal ) 布尔型(bool ) 结构类型(struct) 枚