1.命名空间声明:命名空间是一种特殊的分类机制,它将与一个特定功能有关的全部类型都分组到一块儿。通常将外层命名空间指定为公司名,向内依次是产品名,最后是功能区域,好比Microsoft.Win32.Networking。命名空间中中能够包含句点,这样使得命名空间“显得”井井有条,可是,这只对加强可读性有利,由于编译器认为全部命名空间都在同一个级刷上,数组
例如 System.Collections.Generics 彷佛被包含在 System.Collections 命名空间内部,可是对于编译器来讲.它们是两个完生抽立的,彻底不一样的命名空间。性能
2.using导入的区别:在文件的顶部放置 using 指令和在命名空间声明的内部的顶部放置 using 指令的区别在于,后者的 using 指令只在你声明的那个命名空间内有效,假如在 Awl.Mlchaelis.EssentialCSharp 命名空间的外部又声明了一个新的命名空间,新的命名空间不会受到 using.System指令的影响。不过,不多会这样写代码,尤为是根据约定,每一个文件只应该有一个类型声明。spa
3.using的别名:利用 using 指令为命名空间或类型取一个别名,别名(alias)是在 using 指令所在的那个范围内可使用的一个替代名称。之因此要使用别名,两个最多见的缘由是:消除同名的两个类型的歧义和缩写一个长名称。命令行
4.程序入口方法:Main()方法支持int返回值,而不是仅仅支持vold返回. 退回值对于Main()声明来讲是可选的. 可是,假如使用了它. 程序就能够将一个状态码返回给调用者(调用者能够是一个脚本,也能够是一个批处理文件)。根据约定,一个非零的返回值表明一个错误。虽然全部命令行参数均可以经过一个字符串数组传递给Main(),但咱们有时候可能须要从一个不一样于Main()的方法中访问那些参数,在这种状况下,可使用 System.Environment.GetCommandLineArgs()方法,该方法采起和Main(string[] args)将参数传递给Main()同样的方式来返回命令行参数。设计
5.C#4.0新增:继承
(1)可选参数:可选参数必定放在全部必须的参数(无默认值的参数)后面。另外,默认值必须是一个常量,或者说必须是编译时能肯定的一个值,这-点极大限制了“可选参数”的应用。接口
如:DirectoryCountLines(string directory,string extension="*.cs")开发
(2)命名参数:利用命名参盘,调用者可显式指定参数名.并为该参数赋一个值,而不是像之前那样只能依据参数顺序来决定哪一个值赋给哪一个参数,字符串
如:DisplayGreeting(firstName:"Lucy",lastName:"Jack");编译器
public void DisplayGreeting(string firstName,string middleName=default(string),string lastName=default(string))
{
....省略
}
若是一个方站有大量的参数,并且其中许多都是可选的(访问Microsoft COM库时,这是很常见的-种状况),那么命名参数语法确定能带来很多便利。但要注意的是,这个便利的代价是牺牲方法接口的灵活性,过去{至少就 C#来讲),参数名能够自由更改,不会形成调用代码没法编译的状况. 但在添加了命名参数后,参数名就成为方法接口的一部分,更更名称会致使使用命名参数的代码没法编译。
6.假如方法重载、可选参数和命名参数这几种技术一块儿使用,咱们难以一眼看出最终调用的究竟是哪一个方法,只有在全部参数(可选参数除外)都刚好有一个对应的实参(不论是根据名称仍是位置),并且该实参具备兼容类型的状况下,才说一个调用适用于(兼容于)一个方法。虽然这限制了可调用的方法数量,但还不足以惟一性地标识方法,为了进一步区分方法,编译器只使用调用者显式标识的参数,忽略调用者没有指定的全部可选参数。因此,假如因为一个方法有一个可选参数,形成两个方法都适用,编译器最终选择的将是无可选参数的方法。
编译器从一系列“适用”的方法中选择最终调用的方法时,依据的是哪一个方法最具体,只能有一个方法彻底匹配调用者传递的参数,因此,该方法老是具备最高优先级。
如:调用者传递的是一个 int,那么接受 double 的方法将优先于接受 object 的方法,这是因为 double 比 object 更具体,若是有多个适用的方法,但没法从中挑选出最具惟一性的,编译器就会报错,指明调用存在歧义。在写理序时,最好是使用显式转型,方便别人理解你想调用哪一个目标方法。
7.try-catch-finally的使用:catch由具体到通常,假如在捕捉Exception 的catch 块以后添加了一个具体的 catch 块,编译器就会报告一条警告消息,指出具体的catch块永远都不会执行。没有指定数据类型的 catch 块称为泛化catch块(generic catch block),它等价于获取 object数据类型的catch块。
例如 catch(object exception){ . . . ),因为全部类最终都是从 object派生 , 因此没有数据类型的 catch 块必组出如今最后。泛化的 catch 块不多使用,由于没有办法捕捉有关异常的任何信息。避免使用异常处理来处理预料之中的状况,开发者应当尽可能避免为预料之中的状况或者正常的控制流引起异常,异常是专门为了跟踪例外的、事先没有预料到的、并且可能形成严重后果的状况而设计的,为预料之中的状况使用异常,会形成你的代码难以阅读、理解和维护。
C#在抛出异常时会产生些许性能损失,相较干大多数操做都是纳秒级的速度,它可能形成毫秒级的延迟,人们日常注意不到这个延迟,除非异常没有获得处理。
8.catch块中使用throw:能够在一个catch块中从新引起异常(如在catch(ArgumentNullException ex)的实现中,能够包含对throw ex的调用),而后像这样从新引起异常,会将栈追踪重置为从新引起的位置,而不是重用原始引起位置。在一个catch块的内部,假如你从新引起一个不一样的异常,那么不只会重置引起点,还会隐藏原始异常,为了保留原始异常,须要设置新异常的InnerException属性(该属性一般能够经过构造器来赋值)。
9.自定义异常:自定义异常惟一的硬性要求就是它必须从System.Exception或者其某个子类派生,除此以外,在使用自定义异常的时候,还应遵守如下最佳实践。
(1)全部异常都应该使用“Exception”后缀,彰显其用途。
(2)一般,全部异常都应该包含如下3个构造器:无参数构造器、获取一个string参数的构造器、以及同时获取一个字符串和一个内部异常做为参数的构造器。
(3)避免使用深的继承层次结构(通常应该小于5级)。
10.从NET Framework 4 开始,枚举类型也添加了一个TryParse方法。
-------------------------------------------以上内容根据《C#本质论 第三版》进行整理