改善C#程序的50种方法 读后小记

Effective C# 改善C#程序的50种方法

作者:Bill Wagner

译者:DSQiu

来源:Effective C# 中文版改善C#程序的50种方法 第二版

原则1:使用 属性(Poperty)代替可直接访问的数据成员(Data Member)

原则2:偏爱 readonly 而不是 const

C# 有两种常量:编译时常量和运行时常量。你可以使用 readonly 关键字声明运行时常量,使用 const 关键字声明编译器常量。运行时常量的值是在运行时得到的。当你引用一个只读(read-only)常量, IL 会引用一个 readonly 变量而不是直接使用值。

相比 readonly ,使用 const 最后的一个优势就是性能:已知的常量值会比使用变量访问的 readonly 变量产生稍微高效的代码。然而,性能上甚微的收效和灵活性的减小应该做一个很好的权衡。放弃灵活性之前一定要剖析性能差异。可选参数的默认值会在调用时会像编译时变量(声明为 const 的变量)一样被替换成默认值。和使用 readonly 和 const 变量一样,你要非常认真对待可选参数值的不同。

原则3:选择 is 或 as 而不是强制类型转换

尽可能使用 as ,但是 as 操作符是不能再值类型上使用的。

原则4:使用条件特性(conditional attribute)代替 #if

C# 有一个更好的选择:条件特性。使用条件特性,能分离出不同函数,只有在特定的环境变量的定义或某些值的设置才会属于你的类。

[Conditional("DEBUG")] 
private void CheckState() 
{
// same code as above 
}

原则5:个别情况建议重写C#提供的 ToString()

原则6:理解几个不同相等概念的关系

当你定义类型(类或结构体)时,你同时要定义类型的相等。 C# 提供四种不同的函数决定两个不同对象是否“相等”:

public static bool ReferenceEquals (object left, object right);
public static bool Equals (object left, object right);
public virtual bool Equals(object right); 
public static bool operator ==(MyClass left, MyClass right);

原则7:明白 GetHashCode() 的陷阱

GetHashCode() 只用在一个地方:定义基于哈希 key 集合,典型地, HashSet<T> 或者 Dictionary<K,V> 容器。

任何重写 GetHashCode() 必须遵循下面三个条件:

1.如果两个对象相等(被操作符 == 定义),你产生相同的哈希值。否则哈希码不能用来查找容器中的对象。

2.对任何对象 A , A.GetHashCode() 必须是一个实例不变量。无论什么方法调用 A.GetHashCode() 必须返回相同的值。这保证了一个物体总是存储在正确的桶中。

3.哈希函数应该针对所有输入情况产生一个整数随机分布。这就是为什么基于哈希容器高效。

关于C#的GetHashCode

原则8:优先考虑查询语法

举个例子:

private readonly List<T> datas = new List<T>();

public List<T> FindAll(Predicate<T> match, ref List<T> result,int count = 0)
{
     result.Clear();

     foreach (var pair in datas)
     {
        if (null == pair)
            continue;
        if (null != match && match.Invoke(pair) == false)
            continue;
        result.Add(pair);
        if (0 < count && count <= result.Count)
            break;
    }
    return result;
}

private static bool Check(T t)
{
//TODO
}
private Predicate<T> Checker()
{
    return x => Check(x);
}

原则9:在你的 API 中避免转换操作

原则10:使用默认参数减少函数的重载

原则11:理解小函数的魅力

用多个简短的小函数代替大段代码块组成的函数,目的一是可以增强阅读性和扩展性,二是避免编译器产生额外的开销

短小而简单的函数可以让 JIT 编译器很容易支持寄存器化(enregistration) 。寄存器化是指处理器选择寄存器而不是栈存储局部变量。创建更少的局部变量使得 JIT 编译器更好的找到可用的寄存器。

原则12:选择变量初始化语法(initializer)而不是赋值语句

在变量声明的时候初始化而不是在构造函数内初始化。你应该使用初始化语法为静态变量和实例变量进行初始化。

原则13:使用恰当的方式对静态成员进行初始化

静态成员变量在创建对象实例之前就已经初始化了。C# 提供了静态初始化语法和静态构造函数对静态成员变量进行初始化。静态构造函数是一个比其他函数,变量,属性在没有访问之前就被执行的特殊函数。

和实例初始化一样,静态初始化语法在任何静态构造函数之前执行。并且,你的静态初始化语法比基类的静态构造函数更早执行。

原则14:减少重复的代码块

原则15:使用 using 和 try/finally 清理资源

使用 using 语句可以保证 Dispose() 被调用。你使用 using 语句分配对象,C# 编译器就会产生 try/finally 块包含这些对象:

SqlConnection myConnection = null;
// Example Using clause: 
using (myConnection = new SqlConnection(connString)) 
{
    myConnection.Open(); 
}
// example Try / Catch block: 
try 
{
    myConnection = new SqlConnection(connString); 
    myConnection.Open();
}
finally 
{
    myConnection.Dispose(); 
}

原则16:避免创建不需要的对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值