2009-02-18 15 views
12

Reflektor mówi mi, że SortedList wykorzystuje klasę ThrowHelper rzucać wyjątki zamiast rzucać je bezpośrednio, na przykład:Dlaczego implementacja SortedList używa ThrowHelper zamiast bezpośredniego rzucania?

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

gdzie ThrowKeyNotFoundException nie robi nic więcej niż tylko:

throw new KeyNotFoundException(); 

zauważyć, jak to wymaga Instrukcja duff "return default (TValue)", która jest nieosiągalna. Muszę stwierdzić, że jest to schemat o korzyściach wystarczająco dużych, aby to uzasadnić.

Co to są te korzyści?

+1

Czy spojrzałeś na rzeczywisty kod Microsoft, a nie na to, do czego się on kompilował? –

+1

Nie, nie mam. Czy to jest znacząco różne? Jeśli tak, wyjaśnij to w odpowiedzi! :) –

Odpowiedz

19

Zgodnie z kodem źródłowym ThrowHelper.cs głównym celem jest zmniejszenie wielkości kodu JIT. Poniżej znajduje się bezpośrednia kopia wklej z linku:

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

Zobacz, co robi ThrowHelper. Otrzymuje zasoby i inne informacje dotyczące komunikatów o błędach. W tym konkretnym przypadku nie ma tekstu błędu, więc wydaje się, że jest bezużyteczny, ale ich wzór prawdopodobnie wymaga tego, więc twórca, który napisał, postępował zgodnie ze wzorcem, jak powinien.

Powiązane problemy