为什么SortedList实现使用ThrowHelper而不是直接抛出?
问题描述:
反射告诉我,排序列表使用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)”,这是无法访问的。我必须得出这样的结论:这种模式的好处足以证明这一点。
这些好处是什么?
答
根据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.
答
看看ThrowHelper做了什么。它获取错误消息的资源和内容。在这个特定的例子中,没有错误文本,所以它看起来没用,但是他们的模式可能需要它,所以编写它的开发人员遵循像他/她应该的模式。
你看了看实际的微软代码,而不是它编译到什么? – 2009-02-18 19:31:01