c#2.0有内置的静态类支持。
1 必须使用接口, 对包括值类型在内的一组类型的支持
2 考虑使用接口, 因为不支持多重继承,但可以支持多个接口
3 避免使用记号接口(没有成员的接口),可以使用attibute, 某些情况下也可以使用,知识我们可以避免。
4 要为接口提供至少一种实现的类型,一个API使用这个接口
5 一般来说,设计可重用的程序库时,优先选择类而不是接口。
1 方法表示操作,属性表示数据,在各种条件相同的情况下,优先使用属性。
2 要在下列情况中使用方法而不要使用属性:
3 该操作比字段访问要慢一个或多个数量级。
4 该操作每次返回的结果不同,即使传入的参数不变,例如:Guid.NewGuid方法每次都返回一个不同的值。 DateTime.Now属性应该被设计为方法。
5 该操作有严重的,能观察到的副作用。
6 该操作返回一个数组: 在循环中,属性每次都会返回无数个数组的副本。
7 鼓励换一种方式来记忆:用属性来表示只设计简单计算的数据。不要背离这个原则。
给已经有默认构造函数的现有类增加一个带参数的构造函数是很常见的.如果不小心,那么可能是编译器不再生成默认的构造函数.列入给刚才声明的类增加一个带参数的构造函数会去除默认构造函数.
这会破坏那些依赖于默认构造函数的已有代码, 且在回顾代码时不可能再看到.因此最好的做法是始终显式地提供默认构造函数.
注意, 这不适用于结构.即使结构定义了带参数的构造函数,它们仍会有隐式的默认构造函数.
不要在出发时间时把null作为参数传入。如果不想传传任何数据给时间处理方法,那么应该用EventArgs.Empty.
1 要验证传给共有的, 受保护的或显示实现的成员的参数. 如果验证失败,那么就应该抛出System.ArgumentException或其子类.
2 要抛出ArgumentNullException, 如果传入的是null 而该成员不支持null.
3 要验证枚举参数.
4 避免使用输出参数或引用参数. 作为框架设计者, 如果目标用户很广泛, 那么就不应该期望用户已近知道如何使用输出参数和引用参数.
5 不要在API中过多的使用引用参数和输出参数. 这样的API很难用, 因为它会强迫你声明很多临时变量. 我更倾向于功能性的设计, 在返回值中传回整个结果.
1 要使用最合理, 最具针对性的异常.
2 例如,如果传入的参数是null, 那么应该抛出ArgumentNullException, 而非基类ArgumentException.
3 抛出System.Exception无论如何都是错的,它是所有符合CLS规范的异常的基类.
4 要在进行清理工作时适用try-finally, 避免使用try-catch, 对精心编写的异常代码来说, try-finally的适用频率要比try-catch 高得多.
5 一开始这可能有背直觉, 但令人惊讶的是, 大量的情况下都不需要catch代码块. 另一方面, 在编写代码时始终都应该考虑是否需要在清理时使用try-finally 以确保有异常抛出时系统处于一致的状态. 通常,清理工作就是释放已分配的资源.
1 要在命名名字空间, 类型及成员是采用PascalCasting 大小写风格,除非是内部字段和私有字段.
2 要用camelCasing 大小写风格来命名内部字段和私有字段.
3 要用camelCasing 大小写风格来命名局部变量.
4 要用camelCasing 大小写风格来命名方法的形式参数.
5 不要使用匈牙利命名法.
6 避免给局部变量加前缀.
7 要使用C#语言对应的别名, 不要使用.NET框架中德类型名.
1 不要再一个源文件中包含一个以上的公用类型,除非有嵌套类,或各类型之间的不同之处仅在于泛型参数的数量。
2 一个文件中有多个内部类型是允许的。
3 要用相同的名字来命名源文件及其包含的公用类型。例如,String类应该在String.cs文件中,而List
4 要用相同的层次结构来组织文件目录和命名空间。例如,应该把System.Collections.Generic.List
5 考虑根据下面给出的顺序和组别来对成员进行分组: