《Effective C#》--Bill Wagner
《Effective C#》-- Bill Wagner.
总是使用Properties代替直接访问数据成员。
以前曾经有个误解,认为使用get/set会生成对应的方法,这样会降低效率。实际上,JIT编译器会采用inline方式处理这些方法调用,而内联方法和直接访问数据成员的效率差别是微乎其微的。但是,要注意get/set中如果有try/catch将会阻止编译器生成内联方法。
众所周知的,目前C#1.1中get/set的访问修饰符必须一致,这有时候不能满足设计要求,但幸运的是,在C#2.0中可以get/set可以使用不同的访问修饰符。
索引器只能使用this[]命名,不能重命名,但我实在想不出理由要去重命名indexer.
Item 2: Prefer readonly to const.
尽量使用readonly代替const。
readonly和const的差别:
1) readonly - runtime constants.
const - complie-time constants.
2) const只能是数值和字符串,只能通过=初始化。
readonly可以是实例常量,可以通过new构造。
3) readonly常量是运行期兼容的,一个程序集里面的readonly常量的变更,不需要重新编译引用该常量的其他程序集。
const常量在编译期被赋值,所以一个const常量的变更,将无法使其他引用该常量的其他程序集同步,而必须重新编译。
4) const常量比readonly常量效率稍微高一点,比较适合于自然界恒定量,永远不可能会被改变的量,否则宁愿使用readonly。
Item 3: Prefer the is or as Operators to Casts.
尽量使用is、as操作符代替转换操作(C风格的转换操作)。
程序中应该尽量避免强制类型转换。虽然有时候运行时类型检查不是轻易可以避免的,但是使用is、as的原因很简单,因为它们是安全而优雅的。
Item 4: Use Conditional Attributes Instead of #if.
Item 5: Always Provide ToString().
总是提供ToString()。
Item 6: Distinguish Between Value Types and Reference Type.
Item 7: Prefer Immutable Atomic Value Types.
Item 8: Ensure That 0 Is a Valild State for Value Types.
确定0是值类型的可用状态。
Item 9: Understand the Relationships Among ReferenceEquals(), static Equals(), instance Equals(), and operator==.
理解ReferenceEquals()、静态Equals()、实例Equals()、operator==之间的关系。
Equality is reflexive, symmetric, and transitive.
A) public static bool ReferenceEquals(object left, object right);
B) public static bool Equals(object left, object right);
C) public virtual bool Equals(object right);
D) public static bool operator==(MyClass left, MyClass right);
Conclusion:
1)不需要重些static Object.ReferenceEquals()和static Equals()。
2)总是为值类型重写instance Equals()和operator==()。
3)为引用类型重些instance Equals()。
Item 10: Understand the Pitfalls of GetHashCode().
理解GetHashCode的缺陷。
Item 11: Prefer foreach Loops.
尽可能使用foreach循环。
foreach有边界检查,并且该检查是高效的,经过测试,在CLR1.1中,foreach略微比for循环低一点点,但几乎无影响。但却简洁很多,优雅很多,我喜欢。
Chapter 2 .NET Resource Management
Item 12: Prefer Variable Initializers to Assignment Statements.
Item 13: Initialize Static Class Members with Static Constructors.
Item 14: Utilize Constructor Chaining.
Item 15: Utilize using and try/finally for Resource Cleanup.
Item 16: Minimize Garbage.
Item 17: Minimize Boxing and Unboxing.
Item 18: Implement the Standard Dispose Pattern.
Chapter 3 Expressing Designs with C#
Item 19: Prefer Defining and Implemeting Interfaces to Inheritance.
Item 20: Distinguish Between Implementing Interfaces and Overriding Virtual Functions.
Item 21: Express Callbacks with Delegates.
Item 22: Define Outgoing Interfaces with Events.
Item 23: Avoid Returning references to Internal Class Objects.
Item 24: Prefer Declarative to Imperative Programming.
Item 25: Prefer Serializable Types.
Item 26: Implement Ordering relations with IComparable and IComparer.
Item 27: Avoid ICloneable.
Item 28: Avoid Conversion Operators.
Item 29: Use the new Modifer Only When Base Class Updates Mandate It.
Chapter 4 Creating Binary Components
Item 30: Prefer CLS-Compliant Assemblies.
Item 31: Prefer Small, Simple Functions.
Item 32: Prefer Smaller, Cohesive Assemblies.
Item 33: Limit Visibility of Your Types.
Item 34: Create Large-Grain Web APIs.
Chapter 5 Working with the Framework
Item 35: Prefer Overrides to Event Handlers.
Item 36: Leverage .NET Runtime Diagnostics.
Item 37: Use the Standard Configuration Mechanism.
Item 38: Utilize and Support Data Binding.
Item 39: Use .NET Validation.
Item 40: Match Your Collection to Your Needs.
Item 41: Prefer DataSets to Custom Structures.
Item 42: Utilize Attributes to Simplify Reflection.
Item 43: Don't Overuse Reflection.
Item 44: Create Complete Application-Specific Exception Classes.
Chapter 6 Miscellaneous
Item 45: Prefer the Strong Exception Guarantee.
尽可能使用强异常保证。
曾经写了关于异常处理的一篇文章放在公司内部的开发项目组网站上,可搬了个地方,找起来不方便了。从本人观点是强烈反对将异常作为控制流的一种方式的。同时只处理必须处理的异常也是我的一个原则。或许这有需要再思考改进的地方。
Item 46: Minimize Interop.
Item 47: Prefer Safe Code.
Item 48: Learn About Tools and Resources.
Item 49: Prepare for C# 2.0
Item 50: Learn About the ECMA Standard.