Подтвердить что ты не робот

Почему реализация 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)", которое недостижимо. Я должен сделать вывод, что это шаблон с преимуществами, достаточно большими, чтобы оправдать это.

Каковы эти преимущества?

4b9b3361

Ответ 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.