2009-02-18 4 views
12

réflecteur me dit que SortedList utilise une classe ThrowHelper à jeter des exceptions au lieu de les jeter directement, par exemple:Pourquoi l'implémentation de SortedList utilise-t-elle ThrowHelper au lieu de lancer directement?

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

où ThrowKeyNotFoundException ne fait rien plus que:

throw new KeyNotFoundException(); 

Notez comment cela nécessite un Duff déclaration "return default (TValue)" qui est inaccessible. Je dois conclure que c'est un modèle avec des avantages assez importants pour justifier cela.

Quels sont ces avantages?

+1

Avez-vous regardé le code Microsoft actuel et pas ce qu'il compile? –

+1

Non, je n'ai pas. Est-ce significativement différent? Si c'est le cas, expliquez-le dans une réponse s'il vous plaît! :) –

Répondre

19

Selon le code source ThrowHelper.cs, l'objectif principal est de réduire la taille du code JITTED. Ci-dessous est un copier coller directement à partir du lien:

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

Regardez ce que fait ThrowHelper. Il obtient des ressources et des trucs pour les messages d'erreur. Dans ce cas particulier, il n'y a pas de texte d'erreur, donc il semble que c'est inutile, mais leur modèle l'exige probablement, donc le développeur qui l'a écrit a suivi le modèle comme il le devrait.

Questions connexes