首页 > 从C#2.0的角度看.NET 2.0类型系统

从C#2.0的角度看.NET 2.0类型系统

C#中所有变量使用之前都必须初始化,否则编译器会在初始化时产生一个编译错误。



每个Windows线程都有一个私有的内存区块,称为栈;也就是说这块内存块不能被其他线程访问(特定条件下除外)。什么条件?

线程的栈主要用于:

  • 保存正在执行中的方法的传入实参值;
  • 保存方法返回是需要跳转的本地代码的地址;
  • 保存对象(但不是全部)。
一个进程通常只有(有时也可以有多个)堆,为其下的所有线程所共享。何时?

堆的优点是容量比栈大得多。为所有线程所共享。

栈的优点是速度比堆快。这主要源于专门访问栈的IL指令,以及访问栈上的元素无需同步。

因此,用堆来存储大对象,用栈存储小对象。。

C#中的值类型的实例使用静态分配(分配在线程栈上),而引用类型的实例则使用动态分配(分配在进程堆中)。



结构、枚举是值类型,委托是
引用类型

如果某个类的实例有个值类型的字段,那么该字段会和类实例保存在一起,即堆中。反过来,如果一个结构的字段是引用类型,那么引用类型的实例还是会保存在堆中。



在C#中,求模运算也可以用于浮点数。

float a = 5.5f;

Console.WriteLine(a % 2.5);

屏幕上将输出0.5。

C#语言提供了checked关键字,可以得到验证所有的类型转换和运算。如果有问题就会引发一个异常。



整形和decimal类型被零除时,会产生DivideByZeroException异常。

浮点型float和double被零除时,会得到无穷大,0/0得到Nan。



C#的递增和递减运算符也可以用于浮点数。

float a = 5.5f;

a++;

此时a = 6.5。



C#中的结构不能从其他类或者结构派生,也不能作为其他类型或结构的基类。

C#的结构可以有多个构造函数,当不允许自定义默认的构造函数(即没有参数的构造函数)。而且编译器要求每一个构造函数都初始化结构的所有字段。

默认构造函数将所有值类型的字段设为零,而将所有引用类型的字段设为空引用。

结构可以有自己的方法。

与类的字段不同,结构的字段不能在声明中显示初始化。

结构的实例常常存储在栈中,因此结构不宜太大。太大的结构最好用类代替。



编译器默认情况下,将枚举的值视为int型整数。因此,枚举定义的这组常数中任意一个值都是一个整数。可以对其进行递增、递减操作。

在默认情况下,枚举的第一个值是0,之后的每一个值都是前一个值加1.当然,也可以手工指定自己想要的值。

你也可以定义其他类型的枚举类型的值:

    enum MakerCHB:byte{Beijing,Zhejiang}

    enum MakerCHL:long{Beijing,Zhejiang}



可以让一个枚举的实例包含多个枚举值。这个概念也称为二进制位标志(binary flag)或者标志枚举(flag enum).

注意,位域枚举都打上了System.Flags attribute标志,该attribute通知CLR和客户端这个枚举用来表示位域而不是标准枚举,这个枚举用来表示位域而不是标准枚举。这个标志会影响ToString()方法的结果。最好能有个实例!

.NET Framework中的System.Threading.ThreadState就是采用了二进制标志的枚举。



C#中String类的实例是不可变。即无法修改它们,它们将保持通过构造函数所赋的值不变。

C#允许定义无转义的字符串字面常量,方法就是在字符串起始的双引号之前加入“@”符号。无转义字符串字面常量具有以下特征:

  • 它将接受所有字符作为字符串的内容,包括“”反斜杠字符,不过不包括双引号。
  • 它将接受字符串中的所有换行。
C#是String类的实例是不可变的。使得对所有字符串的修改操作均会分配一个新的String实例。如果应用程序要频繁修改字符串或者处理长字符串,那么更好的方法是使用System.Text.StringBuilder类。

通过不安全代码也可以打破字符串实例的不可变特性。



C#允许用delegate关键字创建一种特殊的类,我们称这种类为委托类。委托类的实例称为委托对象。

委托对象是一种指向一个或多个方法(静态或非静态)的引用。我们可以像调用方法那样“调用”委托对象,这其实就是调用委托对象所引用的方法。注意这些方法的调用是在调用委托的方法所在的线程中完成的,即同步调用。

委托变量所能引用的方法只能是其签名式与委托类声明中所提供的签名式一致的方法。

delegate void Deleg1();

delegate string Deleg2(string s);

delegate void f1()

{

}


static string f2(string s)

{

}


Deleg1 d1 
= new Deleg1(f1);   // right

Deleg2 d2 = new Deleg2(f2);   // right

Deleg2 d3 = new Deleg2(f1);   // error
C# 2.0编译器引入在创建委托变量时推测其类型的功能。于是就可以直接将一个方法赋给隐式创建的对象。如

Deleg1 d1 = f1;

Deleg2 d2 = f2;

但是,其编译生成的IL代码,跟前面的是一样的,它仍旧调用了Deleg1和Deleg2委托类的构造函数。

可以用一个委托对象应用多个具有相同签名式的方法(静态或非静态)。这种情况下调用委托对象就会在调用对象的线程中顺序执行所有的方法。调用方法的顺序就是方法添加到委托对象中的顺序,每个方法的参数都是一样的。

如果委托的签名具有返回值,那么引用多个方法时只有最后一个调用的方法的返回值才作为委托对象的返回值返回。

可以用GetInvocationList()获取该委托对象中的委托列表。



可空类型System.Nullable等价于T?。

    即int? i = null;和Nullable i = null;是等价的。

不过,编译器会阻止从可空类型到原始类型的隐式转换。此外,不事先测试而进行可空类型到原始类型的显示转换也是危险的,因为,这可能会引发InvalidOperationException异常。



C# 2.0允许将类、结构和接口的声明分散到多个源文件中。我们称这一特性命名为部分类型。注意,委托类或者枚举类是不能声明在多个源文件中的。

同一个类型各个不同的部分定义前面必须都加partial关键字。而且,如果该类型是泛型的,那么类型参数的定义也必须出现在每个部分的部分定义上。每个部分定义上类型参数的名称和位置必须完全一致。即在每个部分什么的class、struct或interface关键字之前加partial关键字。而且必须属于同一个命名空间。

更多相关:

  • Python 与 ABC 的一个重要区别在于其类型系统。ABC 采用静态类型,编译器会检查程序中的变量类型是否保持一致,如果不一致,程序就无法运行。并且,ABC与当时大多数静态语言不同,采用的是类型推导(和 Haskell 一样),而不是类型声明(比如 C 语言)。而 Python 采用动态类型,所有类型检查都是在程序运行过程中,而不...

  • python是计算机二级考试的科目之一,并没有级别的划分。其考试目标是测试考生掌握Python语言知识的程度和对Python语言的编程能力、调试能力和综合应用能力,在当下的应用中是十分重要的。 什么是python Python语言是一种解释运行、面向对象、扩展性强的程序设计语言,是大学生学习计算机编程能力、理解计算机解决问题的方法的...

  • 正在学C,书上老说空指针,或者说void指针,对于我这样的生手来说,理解非常容易造成混淆,因为void这个单词的意思也是空,到底空指针的意思是指指向地址为空的类型呢,还是指void类型的指针呢 (1)空指针所对应的是指指向的对象为空的指针。            不经发问,什么叫指向为空呢?要理解这点,必须理解如下几点(有点啰嗦,但...

  • 一、reponseType 1、什么是reponseType XMLHttpRequest.reponseType属性是一个枚举类型的属性,返回响应数据的类型,他允许我们手动的设置 返回数据的类型。如果我们将它设置为一个空字符串,它将默认的使用"text"类型。 当将reponseType设置为一个特定的类型的时候需要确保服务...

  • SNMP中,数据类型并不多。这里我们就讨论这些数据类型,而不关心这些数据类型在实际中是如何编码的。INTEGER一个变量虽然定义为整型,但也有多种形式。有些整型变量没有范围限制,有些整型变量定义为特定的数值(例如,IP的转发标志就只有允许转发时的或者不允许转发时的这两种),有些整型变量定义一个特定的范围(例如,UDP和TCP的端口号...

  • 来源:公众号|计算机视觉工坊(系投稿)作者:仲夏夜之星「3D视觉工坊」技术交流群已经成立,目前大约有12000人,方向主要涉及3D视觉、CV&深度学习、SLAM、三维重建、点云后处理、自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、...

  • 点云PCL免费知识星球,点云论文速读。文章:Real-Time LIDAR-Based Urban Road and Sidewalk Detection for Autonomous Vehicles作者:Ern˝o Horváth  , Claudiu Pozna ,and Miklós Unger编译:点云PCL代码:http...

  • 文章:Semantic Histogram Based Graph Matching for Real-Time Multi-Robot Global Localization in Large Scale Environment作者:Xiyue Guo, Junjie Hu, Junfeng Chen, Fuqin Deng, T...

  • 点云PCL免费知识星球,点云论文速读。文章:Robust Place Recognition using an Imaging Lidar作者:Tixiao Shan, Brendan Englot, Fabio Duarte, Carlo Ratti, and Daniela Rus编译:点云PCL(ICRA 2021)开源代码:...

  • 文章:A Survey of Calibration Methods for Optical See-Through Head-Mounted Displays作者:Jens Grubert , Yuta Itoh, Kenneth Moser编译:点云PCL本文仅做学术分享,如有侵权,请联系删除。欢迎各位加入免费知识星球,获取PD...

  • 委托揭秘 编译器和CLR在后台做了很多工作来隐藏委托本身的复杂性,如下一句委托声明: //编译器为我们产生了一个同名的类 public delegate void MyDelegate(int i); 看看IL: 可以看出它默认继承自System.MulticastDelegate[所有委托都继承此类,MulticastDele...