Item 16: Avoid Creating Unnecessary Objects 避免创建不必要的对象
- GC内存管理上做的很好,而且它会高效的移除没用的对象。但是不要让他工作过度,你可以通过一些简单的方法来最小化GC的工作量。下面来看例子
// Sample one
protected override void OnPaint(PaintEventArgs e)
{
// Bad. Created the same font every paint event.
using (Font MyFont = new Font("Arial", 10.0f))
{
e.Graphics.DrawString(DateTime.Now.ToString(),
MyFont, Brushes.Black, new PointF(0, 0));
}
base.OnPaint(e);
}private readonly Font myFont =new Font("Arial", 10.0f);
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawString(DateTime.Now.ToString(),
myFont, Brushes.Black, new PointF(0, 0));
base.OnPaint(e);
} - 下面我们来看上面例子中的静态属性Brushes.Black。假如每次你在你的window上画画都用黑色,那么就要黑色的刷子。而你每次为了画画都创建一个新的刷子,然后再销毁,而且我们可能还会用到很多其他的工具,这样会显得低效。因此我们需要做这样的一个简单实现
private static Brush blackBrush;
public static Brush Black
{
get
{
if (blackBrush == null)
blackBrush = new SolidBrush(Color.Black);
return blackBrush;
}
}当你第一次请求一个黑色刷子时,Brushes类会创建它,而且保留了一个对唯一黑色刷子的引用,当你再次用到它的时候,它就会返回原来的刷子。也就是说,创建一个刷子,永远使用。
-
第三个技巧包含:为不可变的类型创建终值。System.String就是不可变的:当你创建了一个string类型,string的内容是不可修改的。
string msg = "Hello, ";
msg += thisUser.Name;
msg += ". Today is ";
msg += System.DateTime.Now.ToString();
is just as inefficient as if you had written this:
string msg = "Hello, ";
// Not legal, for illustration only:
string tmp1 = new String(msg + thisUser.Name);
msg = tmp1; // "Hello " is garbage.
string tmp2 = new String(msg + ". Today is ");
msg = tmp2; // "Hello <user>" is garbage.
string tmp3 = new String(msg + DateTime.Now.ToString());
msg = tmp3; // "Hello <user>. Today is " is garbage.
因此这里我们使用StringBuilder类StringBuilder msg = new StringBuilder("Hello, ");
msg.Append(thisUser.Name);
msg.Append(". Today is ");
msg.Append(DateTime.Now.ToString());
string finalMsg = msg.ToString();