每一个C#开发者必须知道的12件事情
1.开发流程
程序的Bug与瑕疵往往出现于开发流程当中。只要对工具善加利用,就有助于在你发布程序之前便将问题发现,或避开这些问题。
2.类型的陷阱
C#的一个主要的优点就是其灵活的类型系统,而安全的类型可以帮助我们更早地找到错误。通过强制执行严格的类型规则,编译器能够帮助你维持良好的代码书写习惯。在这一方面,C#语言与.NET框架为我们提供了大量的类型,以适应绝大多数的需求。虽然许多开发者对一般的类型有着良好的理解,并且也知晓用户的需求,但是一些误解与误用仍然存在。
更多关于.NTE框架类库的信息请参阅MSDNlibrary。
3.类的陷阱(封装你的数据)
类在恰当管理数据方面起很大的作用。鉴于性能上的一些原因,类总是缓存部分结果,或者是在内部数据的一致性上做出一些假设。使数据权限公开的话会在一定程度上让你去缓存,或者是作出假设,而这些操作是通过对性能、安全性、并发性的潜在影响表现出来的。例如暴露像泛型集合、数组之类的易变成员项,可以让用户跳过你而直接进行结构体的修改。
4.泛型
泛型是一种在定义独立类型结构体与设计算法上一种十分有力的工具,它可以强制类型变得安全。
用像List<T>这样的泛型集来替代数组列表这种无类型集,既可以提升安全性,又可以提升性能。
在使用泛型时,我们可以用关键词“default”来为类型获取缺省值(这些缺省值不可以硬编码写进implementation)。特别要指出的是,数字类型的缺省值是o,引用类型与空类型的缺省值为null。
5.类型转换
类型转换有两种模式。其一显式转换必须由开发者调用,另一隐式转换是基于环境下应用于编译器的。
常量o可由隐式转换至枚举型数据。当你尝试调用含有数字的方法时,可以将这些数据转换成枚举类型。
6.异常
异常并不是condition
异常不应该常出现在程序流程中。它们代表着开发者所不愿看到的运行环境,而这些很可能无法修复。如果你期望得到一个可控制的环境,那么主动去检查环境会比等待问题的出现要好得多。
利用TryParse()方法可以很方便地将格式化的串转换成数字。不论是否解析成功,它都会返回一个布尔型结果,这要比单纯返回异常要好很多。
7.事件
事件与委托共同提供了一种关于类的方法,这种方法在有特殊的事情发生时向用户进行提醒。委托事件的值在事件发生时应被调用。事件就像是委托类型的域,当对象生成时,其自动初始化为null。
事件也像值为“组播”的域。这也就是说,一种委托可以依次调用其他委托。你可以将一个委托分配给一个事件,你也可以通过类似-=于+=这样的操作来控制事件。
8.属性
属性提供了一种向程序集、类与其信息属性中注入元数据的方法。它们经常用来提供信息给代码的消费者——比如debugger、框架测试、应用——通过反射这一方式。你也可以向你的用户定义属性,或是使用预定义属性
9.Debug
Debug是在开发过程中必不可少的部分。除了使运行环境不透明的部分变得可视化之外,debugger也可以侵入运行环境,并且如果不使用debugger的话会导致应用程序变现有所不同。
10.性能优化
早做计划,不断监测,后做优化
在设计阶段,制定切实可行的目标。在开发阶段,专注于代码的正确性要比去做微调整有意义的多。对于你的目标,你要在开发过程中多进行监测。只需要在你没有达到预期的目标的时候,你才应该去花时间对程序做一个调整。
请记住用合适的工具来确保性能的经验性测量,并且使测试处于这样一种环境当中:可反复多次测试,并且测试过程尽量与现实当中用户的使用习惯一致。
当你对性能进行测试的时候,一定要注意你真正所关心的测试目标是什么。在进行某一项功能的测试时,你的测试有没有包含这项功能的调用或者是回路构造的开销?
我们都听说过很多比别人做得快很多的项目神话,不要盲目相信这些,试验与测试才是实在的东西。
11.资源管理
垃圾收集器(garbagecollector)可以自动地清理内存。即使这样,一切被抛弃的资源也需要适当的处理——特别是那些垃圾收集器不能管理的资源。
12.并发性
处理并发性与多线程编程是件复杂的、困难的事情。在将并发性添加进你的程序之前,请确保你已经明确了解你的做的是什么——因为这里面有太多门道了!
多线程软件的情况很难进行预测,比如很容易产生如竞争条件与死锁的问题,而这些问题并不是仅仅影响单线程应用。基于这些风险,你应该将多线程视为最后一种手段。如果不得不使用多线程,尽量缩减多线程同时使用内存的需求。如果必须使线程同步,请尽可能地使用最高等级的同步机制。