2009-02-18 91 views
12

反射告訴我,排序列表使用ThrowHelper類,而不是拋出異常直接丟給他們,例如:爲什麼SortedList實現使用ThrowHelper而不是直接拋出?

public TValue this[TKey key] 
{ 
    get 
    { 
     int index = this.IndexOfKey(key); 
     if (index >= 0) 
      return this.values[index]; 
     ThrowHelper.ThrowKeyNotFoundException(); 
     return default(TValue); 
    } 

其中ThrowKeyNotFoundException什麼都不做的不僅僅是:

throw new KeyNotFoundException(); 

注意如何,這需要一個duff語句「return default(TValue)」,這是無法訪問的。我必須得出這樣的結論:這種模式的好處足以證明這一點。

這些好處是什麼?

+1

你看了看實際的微軟代碼,而不是它編譯到什麼? – 2009-02-18 19:31:01

回答

19

根據ThrowHelper.cs源代碼的主要目的是減少JITted代碼的大小。下面是從鏈接直接複製粘貼:

// This file defines an internal class used to throw exceptions in BCL code. 
// The main purpose is to reduce code size. 
// 
// The old way to throw an exception generates quite a lot IL code and assembly code. 
// Following is an example: 
//  C# source 
//   throw new ArgumentNullException("key", Environment.GetResourceString("ArgumentNull_Key")); 
//  IL code: 
//   IL_0003: ldstr  "key" 
//   IL_0008: ldstr  "ArgumentNull_Key" 
//   IL_000d: call  string System.Environment::GetResourceString(string) 
//   IL_0012: newobj  instance void System.ArgumentNullException::.ctor(string,string) 
//   IL_0017: throw 
// which is 21bytes in IL. 
// 
// So we want to get rid of the ldstr and call to Environment.GetResource in IL. 
// In order to do that, I created two enums: ExceptionResource, ExceptionArgument to represent the 
// argument name and resource name in a small integer. The source code will be changed to 
// ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key, ExceptionResource.ArgumentNull_Key); 
// 
// The IL code will be 7 bytes. 
// IL_0008: ldc.i4.4 
// IL_0009: ldc.i4.4 
// IL_000a: call  void System.ThrowHelper::ThrowArgumentNullException(valuetype System.ExceptionArgument) 
// IL_000f: ldarg.0 
// 
// This will also reduce the Jitted code size a lot. 
4

看看ThrowHelper做了什麼。它獲取錯誤消息的資源和內容。在這個特定的例子中,沒有錯誤文本,所以它看起來沒用,但是他們的模式可能需要它,所以編寫它的開發人員遵循像他/她應該的模式。

相關問題