《CLR via C#》读书笔记(5)基元类型、引用类型和值类型
编译器直接支持的数据类型称为基元类型(primitive type)。
int a = 0; //最方便的语法
System.Int32 b = 0; //方便的语法
int c = new int(); //不方便的语法
System.Int32 d = new System.Int32(); //最不方便的语法
|
C#中的基元类型 |
FCL类型 |
是否与CLS兼容 |
描述 |
|
sbyte |
System.SByte |
N |
有符号8位值 |
|
byte |
System.Byte |
Y |
无符号8位值 |
|
short |
System.Int16 |
Y |
有符号16位值 |
|
ushort |
System.UInt16 |
N |
无符号16位值 |
|
int |
System.Int32 |
Y |
有符号32位值 |
|
uint |
System.UInt32 |
N |
无符号32位值 |
|
long |
System.Int64 |
Y |
有符号64位值 |
|
ulong |
System.UInt64 |
N |
无符号64位值 |
|
char |
System.Char |
Y |
16位Unicode字符(不像非托管C++中那样,char表示的是一个8位值) |
|
float |
System.Single |
Y |
IEEE32位浮点数 |
|
double |
System.Double |
Y |
IEEE 64位浮点数 |
|
bool |
System.Boolean |
Y |
一个True或者Flase值 |
|
decimal |
System.Decimal |
Y |
128位高精度浮点值,通常用于不容许有摄入误差的金融计算场合。在这128位中,1位表示浮点值的符号,96位表示浮点值本身(一个整数值,小数点位置由下面8个位来确定),8位表示用96位值除以浮点值所得结果的10的幂次(0~28)。其余的位尚未使用 |
|
string |
System.String |
Y |
一个字符数组 |
|
object |
System.Object |
Y |
所有类型的基类型 |
|
dynamic |
System.Object |
Y |
对于CLR, dynamic 和 object 完全一致。然而,C#编译器允许使用一个简单的语法,让dynamic变量参与动态调度。 |
- 尽量使用有符号的数值类型(比如 Int32 和 Int64),而不要使用无符号的数值类型(比如 UInt32 和 UInt64),这允许编译器检测更多的上溢/下溢错误。
- 如果代码发生不希望的溢出(可能因为无效的输入数据发生的),就把这些代码放在 checked 块中。同时还应捕捉 OverflowException。
- 将允许发生溢出的代码显示的放在一个 unchecked 块中,比如一个计算校验和(checksum)的时候。
- 引用类型总是从托管堆上分配
- 对象中的其他字节总设为零
- 从托管堆上分配一个对象时,可能强制执行一次垃圾收集操作
- 值类型一般在线程栈上分配
- 值类型并不包含一个指向实例的指针,相反,它包含了实例本身的字段,
- 值类型的实例不受垃圾回收站的控制
- 所有结构都是 System.ValueType 直接派生类,所有枚举都是从 System.Enum 的抽象类派生,后者又是从 System.ValueType 派生
1装箱
struct Point
{
public Int32 x, y;
}
public sealed class Program1
{
public static void Main()
{
ArrayList a = new ArrayList();
Point p;
for (int i = 0; i < 10; i++)
{
p.x = p.y = i;
a.Add(p); //对值类型进行装箱,并将引用添加到 ArrayList 中
}
Console.Read();
}
}
1.在托管堆中分配内存。分配的内存量是值类型的各个字段需要的内存量加上托管堆的所有对象都有的两个额外成员(类型对象指针和同步索引块)需要的内存量。
2.值类型的字段赋值到新分配的堆内存。
3.返回对象的地址。值类型现在是一个引用类型。
2拆箱
Int32 x = 5;
Object o = x;
Int16 y = (Int16)o; //抛出一个“InvalidCastException”类型的未经处理的异常
下面代码演示了涉及装箱和拆箱的几种情形
class CLass2
{
static void Main()
{
Point p1 = new Point(10, 10);
Point p2 = new Point(20, 20);
//调用ToString(一个虚方法)时,不会对p1进行装箱
Console.WriteLine(p1.ToString());
//调用GetType(一个非虚方法)时,要对p进行装箱
Console.WriteLine(p1.GetType());
//第一次调用CompareTo时,不会对p1进行装箱
//由于调用的是CompareTo(Point),所以对p2不会装箱
Console.WriteLine(p1.CompareTo(p2));
//p1要进行装箱,将引用放到c中
IComparable c = p1;
Console.WriteLine(c.GetType());
//第二次调用CompareTo时,p1不需要装箱
//由于向CompareTo传递的不是一个Point变量,所以调用CompareTo(object),要求获取一个已装箱的 Point 的引用
//c不会装箱,因为它引用的本来就是一个已经装箱的 Point
Console.WriteLine(p1.CompareTo(c));
//第上次调用CompareTo时,C不需要装箱,因为它引用的本来就是一个已经装箱的Point
//p2会被装箱,因为调用的是CompareTo(object)
Console.WriteLine(c.CompareTo(p2));
//对 c 进行拆箱,字段复制到 p2 中
p2 = (Point)c;
//证明字段已经复制到p2中
Console.WriteLine(p2.ToString());
Console.Read();
}
}
internal struct Point : IComparable
{
private Int32 m_x, m_y;
public Point(Int32 x, Int32 y)
{
m_x = x;
m_y = y;
}
public override string ToString()
{
return string.Format("{0},{1}", m_x, m_y);
}
//实现类型安全的 CompareTo方法
public Int32 CompareTo(Point other)
{
//使用勾股定力来计算哪个point的距离原点(0,0)更远
return Math.Sign(
Math.Sqrt(m_x * m_x + m_y * m_y) - Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y)
);
}
//实现IComparable的CompareTo方法
public int CompareTo(object obj)
{
if (GetType() != obj.GetType())
{
throw new ArgumentException("obj is not a Point");
}
//调用类型安全的CompareTo方法
return CompareTo((Point)obj);
}
}
internal class DynamicDemo
{
static void Main()
{
for (int demo = 0; demo < 2; demo++)
{
dynamic arg = (demo == 0) ? (dynamic)5 : (dynamic)"A";
dynamic result = Plus(arg);
M(result);
//M(Int32):10
//M(String):AA
}
Console.Read();
}
private static dynamic Plus(dynamic arg) { return arg + arg; }
private static void M(int n) { Console.WriteLine("M(Int32):" + n); }
private static void M(string s) { Console.WriteLine("M(String):" + s); }
}
《CLR via C#》读书笔记(5)基元类型、引用类型和值类型的更多相关文章
- [Clr via C#读书笔记]Cp5基元类型引用类型值类型
Cp5基元类型引用类型值类型 基元类型 编译器直接支持的类型,基元类型直接映射到FCL中存在的类型. 作者希望使用FCL类型名称而避免使用关键字.他的理由是为了更加的清晰的知道自己写的类型是哪种.但是 ...
- CLR via C#(02)-基元类型、引用类型、值类型
http://www.cnblogs.com/qq0827/p/3281150.html 一. 基元类型 编译器能够直接支持的数据类型叫做基元类型.例如int, string等.基元类型和.NET框架 ...
- [CLR via C#]引用类型和值类型
一.引用类型与值类型的区别 CLR支持两种类型:引用类型和值类型.引用类型总是从托管堆上分配的,C#的new操作符会返回对象的内存地址.使用引用类型时,必须注意到一些性能问题. 1)内存必须从托管堆上 ...
- 《CLR via C#》读书笔记--基元类型、引用类型和值类型
编程语言的基元类型 编译器直接支持的数据类型称为基元类型.基元类型直接映射到Framework类库中存在的类型.例如:C#中的int直接映射到System.Int32类型.下表给出了C#基元类型与对应 ...
- CLR via C#深解笔记三 - 基元类型、引用类型和值类型 | 类型和成员基础 | 常量和字段
编程语言的基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们. System.Int32 a = new System.Int32(); // a = 0 a = 1 ...
- <NET CLR via c# 第4版>笔记 第5章 基元类型、引用类型和值类型
5.1 编程语言的基元类型 c#不管在什么操作系统上运行,int始终映射到System.Int32; long始终映射到System.Int64 可以通过checked/unchecked操作符/语句 ...
- 【CLR Via C#】第5章 基元类型、引用类型、值类型
第二遍看这本书,决定记录一下加深印象. 1,基元类型 什么事基元类型?基元类型是直接映射到FrameWork类库(FCL)中存在的类型,编译器直接支持的数据类型.比如int直接映射到System.In ...
- 重温CLR(四)基元类型、引用类型、值类型
编程语言的基元类型 编译器直接支持的数据类型称为基元类型(primitive type).基元类型直接映射到framework类型(fcl)中存在的类型. 下表列出fcl类型 从另一个角度,可以认为C ...
- CLR VIA C#: 基元类型、 引用类型 和 值类型
一.基元类型 . 引用类型 和 值类型的区别: 1.基元类型(primitive type):编译器直接支持的数据类型: 基元类型 直接映射到 FCL 中存在的类型. C# 小写是基元类型,例如:st ...
随机推荐
- Understand:高效代码静态分析神器详解(转)
之前用Windows系统,一直用source insight查看代码非常方便,但是年前换到mac下面,虽说很多东西都方便了,但是却没有了静态代码分析工具,很幸运,前段时间找到一款比source ins ...
- [POJ1328]Radar Installation
[POJ1328]Radar Installation 试题描述 Assume the coasting is an infinite straight line. Land is in one si ...
- [codevs1022]覆盖
[codevs1022]覆盖 试题描述 有一个N×M的单位方格中,其中有些方格是水塘,其他方格是陆地.如果要用1×2的矩阵区覆盖(覆盖过程不容许有任何部分重叠)这个陆地,那么最多可以覆盖多少陆地面积. ...
- 小白死去活来的安装ros_qtc_plugin
在距离写上一篇有关ROS的文章已经过去了很久了.在这段时间内一直在积累,盼望着能够厚积薄发,但还是被无情的社会折磨的死去活来,深深的体会到了一般学校和重点学校找工作的差别,以及用人单位的区别对待.说到 ...
- centos7 开机/etc/rc.local 不执行的问题
最近发现centos7 的/etc/rc.local不会开机执行,于是认真看了下/etc/rc.local文件内容的就发现了问题的原因了 #!/bin/bash # THIS FILE IS ADDE ...
- HDU 1503 带回朔路径的最长公共子串
http://acm.hdu.edu.cn/showproblem.php?pid=1503 这道题又WA了好几次 在裸最长公共子串基础上加了回溯功能,就是给三种状态各做一个 不同的标记.dp[n][ ...
- Linux的目录结构
学习Linux这么久,对Linux的目录的目录结构进行整理总结一下. 以下是对这些目录的解释: /bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令. /boot:这里存放的是启动L ...
- ubuntu下文件内容查找命令
Linux查找文件内容的常用命令方法. 从文件内容查找匹配指定字符串的行: $ grep "被查找的字符串" 文件名 例子:在当前目录里第一级文件夹中寻找包含指定字符串的.in文件 ...
- AngularJS概述&指令
AngularJS 指令 AngularJS 应用组成如下: View(视图), 即 HTML. Model(模型), 当前视图中可用的数据. Controller(控制器), 即 JavaScrip ...
- LIGHTSWITCH 连接 MYSQL,中文字符不能保存----解决方法。
使用:dotConnect for MySQL () 作为 数据库连接的PROVIDER , 在 LIGHTSWITCH 中 引用外部的MYSQL 数据源. http://www.devart.co ...