前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《CLR via C#》Part2之Chapter5 基元类型、引用类型和值类型(一)

《CLR via C#》Part2之Chapter5 基元类型、引用类型和值类型(一)

作者头像
Isaac Zhang
发布2019-09-10 18:10:49
3820
发布2019-09-10 18:10:49
举报
文章被收录于专栏:奔跑的人生奔跑的人生

本章内容

  • 编程语言的基元类型
  • 引用类型和值类型
  • 值类型的装箱和拆箱
  • 对象哈希码
  • dynamic基元类型

本章目的

通过学习了解基元类型、引用类型和值类型的区别,希望让coder能避免引用一些不易察觉的bug,并提高性能。

编程语言的基元类型

代码语言:javascript
复制
   1:  //分配一个整数
代码语言:javascript
复制
   2:  System.Int32 a = new System.Int32();
代码语言:javascript
复制
   3:  //C#中我们使用
代码语言:javascript
复制
   4:  int a = 0;

<!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } -->

如上代码,某些类型很常用,许多编译器允许简化他们的语法,而且生成的IL代码与使用System.Int32生成的IL代码完全一致。

编译器直接支持的数据类型称为基元类型(primitive type)

基元类型直接映射到Framework类库(FCL)中存在的类型,比如C#中,int直接映射到System.Int32类型,因此,以下4行代码都能正确编译,并生成完全一致的IL:

代码语言:javascript
复制
   1:  int a = 0;//最方便
代码语言:javascript
复制
   2:  System.Int32 a =0; //方便
代码语言:javascript
复制
   3:  int a = new int();//不方便
代码语言:javascript
复制
   4:  System.Int32 a = new System.Int32();//最不方便

<!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } -->

对于都支持CLS(common language specification公共语言规范)的类型,VS的其他语言都将提供类似的基元类型。对于非CLS的类型不要求。

下图标明了C#中的对应FCL的基元类型:

2013-3-10 21-57-28
2013-3-10 21-57-28

在这里我们建议大家通常在使用类型的时候,使用FCL的类型名称,比如Int32 a = 0; String isaac = String.Empty等。

checked和unchecked基元类型操作

对基元类型执行的许多算术运算都可能造成溢出,如下:

代码语言:javascript
复制
   1:  Byte b = 100;
代码语言:javascript
复制
   2:  b = (Byte)(b+200);//b现在包含44(或者16进制2C)

<!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } -->

在大多数情况下,这种悄然的溢出是我们不希望的。因为它会引起应用程序的异常。但在极少情况下,比如计算一个哈希值或者校验和,这种溢出是可接受的,甚至是希望的。

2013-3-10 22-18-30
2013-3-10 22-18-30

不同的语言对于溢出的处理不同,比如C/C++不认为溢出是个错误,而VB总是将溢出视为错误,检查到后会抛出异常。

C#允许程序员自己决定如何处理溢出,默认检查时关闭状态。C#通过提供checked和unchecked操作符来实现。如下:

代码语言:javascript
复制
//unchecked
UInt32 isvalid = unchecked((UInt32)(-1));//OK
//checked
Byte b = 100;
b = checked((Byte)(b+200));//抛出OverflowException
or
b = (Byte)checked(b+200);//b包含44,不会抛出异常了。。

<!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } -->

除了checked和unchecked操作符之外,C#还支持checked和unchecked语句块,以便标识当前块中所有的表达式都进行或者不进行溢出检查:

代码语言:javascript
复制
checked{
      Byteb = 100;
      b = (Byte)(b+200);//这里要进行溢出检查
}
//因为用了checked块,就可以使用+=的简化代码
checked{
     Byte b = 100;
     b+=200;
}
代码语言:javascript
复制

<!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } -->

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013-03-10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本章内容
  • 本章目的
    • 编程语言的基元类型
      • checked和unchecked基元类型操作
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档