登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

There's always a way

out. You just have to find it.

 
 
 

日志

 
 

值类型与引用类型   

2008-03-10 11:40:43|  分类: C#基础 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1. 通用类型系统
C#的基本数据类型都以平台无关的方式来定义。C#的预定义类型并没有内置于语言中,而是内置于.NET

Framework中。.NET使用通用类型系统(CTS)定义了可以在中间语言(IL)中使用的预定义数据类型,所有

面向.NET的语言都最终被编译为IL,即编译为基于CTS类型的代码。

例如,在C#中声明一个int变量时,声明的实际上是CTS中System.Int32的一个实例。这具有重要的意义:
(1). 确保IL上的强制类型安全;
(2).实现了不同.NET语言的互操作性;
(3).所有的数据类型都是对象。它们可以有方法,属性,等。例如:
int i;
i = 1;
string s;
s = i.ToString();

2. 值类型
C#的所有值类型均隐式派生自System.ValueType:
结构体:struct(直接派生于System.ValueType);
数值类型:
       整型:sbyte(System.SByte的别

名),short(System.Int16),int(System.Int32),long(System.Int64),byte(System.Byte),ushort(

System.UInt16),uint(System.UInt32),ulong(System.UInt64),char(System.Char);
       浮点型:float(System.Single),double(System.Double);
       用于财务计算的高精度decimal型:decimal(System.Decimal)。
       bool型:bool(System.Boolean的别名);
用户定义的结构体(派生于System.ValueType)。
枚举:enum(派生于System.Enum);
可空类型(派生于System.Nullable<T>泛型结构体,T?实际上是System.Nullable<T>的别名)。

每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值。例如:
int i = new int();
等价于:
Int32 i = new Int32();
等价于:
int i = 0;
等价于:
Int32 i = 0;

使用new运算符时,将调用特定类型的默认构造函数并对变量赋以默认值。在上例中,默认构造函数将值0赋给

了i。

所有的值类型都是密封(seal)的,所以无法派生出新的值类型。

值得注意的是,System.ValueType直接派生于System.Object。即System.ValueType本身是一个类类型,而不

是值类型。其关键在于ValueType重写了Equals()方法,从而对值类型按照实例的值来比较,而不是引用地址来

比较。

可以用Type.IsValueType属性来判断一个类型是否为值类型:

TestType testType = new TestType ();
if (testTypetype.GetType().IsValueType)
{
    Console.WriteLine("{0} is value type.", testType.ToString());
}

3. 引用类型
C#有以下一些引用类型:
数组(派生于System.Array)
用户用定义的以下类型:
类:class(派生于System.Object);
接口:interface(接口不是一个“东西”,所以不存在派生于何处的问题。Anders在《C# Programming

Language》中说,接口只是表示一种约定[contract]);
委托:delegate(派生于System.Delegate)。
object(System.Object的别名);
字符串:string(System.String的别名)。
可以看出:

引用类型与值类型相同的是,结构体也可以实现接口;
引用类型可以派生出新的类型,而值类型不能;
引用类型可以包含null值,值类型不能(可空类型功能允许将 null 赋给值类型);
引用类型变量的赋值只复制对对象的引用,而不复制对象本身。而将一个值类型变量赋给另一个值类型变量时

,将复制包含的值。
对于最后一条,经常混淆的是string。我曾经在一本书的一个早期版本上看到String变量比string变量效率高;我

还经常听说String是引用类型,string是值类型,等等。例如:

string s1 = "Hello, ";
string s2 = "world!";
string s3 = s1 + s2;//s3 is "Hello, world!"

这确实看起来像一个值类型的赋值。再如:
string s1 = "a";
string s2 = s1;
s1 = "b";//s2 is still "a"
改变s1的值对s2没有影响。这更使string看起来像值类型。实际上,这是运算符重载的结果,当s1被改变

时,.NET在托管堆上为s1重新分配了内存。这样的目的,是为了将做为引用类型的string实现为通常语义下的字

符串。

  评论这张
 
阅读(455)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018