Почему реализация SortedList использует 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

Согласно ThrowHelper.cs, основной целью является уменьшение размера JIT-кода. Ниже приведена прямая копия папок по ссылке:

// 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. 

Ответ 2

Посмотрите, что делает ThrowHelper. Он получает ресурсы и прочее для сообщений об ошибках. В этом конкретном случае текст ошибки отсутствует, поэтому кажется, что он бесполезен, но его шаблон, вероятно, требует его, поэтому разработчик, который его написал, следовал шаблону, например s/he.