2009-10-29 1 views
3

AssemblyInstaller.Install attend un System.Collections.IDictionary. Ai-je raison d'être «allergique» à l'utilisation de collections non génériques comme Hashtable ou devrais-je m'en remettre?Est-il correct de transmettre un dictionnaire générique en tant que param à une méthode attendue IDictionary?

par exemple.

using System.Collections.Generic; 
using System.Configuration.Install; 
using System.Reflection; 
using AssemblyWithInstaller; 

namespace InstallerDemo 
{ 
    class InstallerDemo 
    { 
     static void Main(string[] args) 
     { 
      var savedState = new Dictionary<object, object>(); 
      // i.e. as opposed to something that implements IDictionary: 
      //var savedState = new System.Collections.Hashtable() 
      var assembly = Assembly.GetAssembly(typeof (MyInstaller)); 
      var ai = new AssemblyInstaller(assembly, new[] {"/LogFile=install.log"}); 
      ai.Install(savedState); 
      ai.Commit(savedState); 
     } 
    } 
} 

De plus, le compilateur n'a pas de problème avec ce decalration:

var savedState = new Dictionary<string, object>(); 

Mais sera quelque chose de mauvais se lors de l'exécution si quelqu'un utilise autre chose que des chaînes comme clés?


Mise à jour [réflecteur à la rescousse]

var savedState = new Dictionary<string, object>(); 

Confirmant ce que dit Jon, Dictionnaire implémente IDictionary comme suit:

void IDictionary.Add(object key, object value) 
{ 
    Dictionary<TKey, TValue>.VerifyKey(key); 
    Dictionary<TKey, TValue>.VerifyValueType(value); 
    this.Add((TKey) key, (TValue) value); 
} 

... donc à vérifier la clé, il lancera une exception lorsque le type de la clé ne correspond pas à celui utilisé lors de la déclaration de la spécialisation particulière du dictionnaire générique (et de même pour la pe de la valeur):

private static void VerifyKey(object key) 
{ 
    if (key == null) 
    { 
     ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key); 
    } 
    if (!(key is TKey)) 
    { 
     ThrowHelper.ThrowWrongKeyTypeArgumentException(key, typeof(TKey)); 
    } 
} 

Répondre

2

Cela fonctionne parce que Dictionary<TKey, TValue> implémente IDictionary - mais il sera en effet l'échec au moment de l'exécution si quelqu'un appelle IDictionary.Add(object, object) avec une clé non-string - vous obtiendrez un ArgumentException.

Notez que lui-même ne couvre pas l'interface IDictionary<TKey, TValue>IDictionary - il est juste que la mise en œuvre Dictionary<TKey, TValue>également implémente IDictionary.

+0

OK, bon à savoir, merci. Mais quelle est votre opinion sur le fait qu'il vaut mieux que je préfère Dictionary sur HashTable? Au moins de cette façon, je communique mieux ce que je (maintenant sais) est l'exigence de cet usage particulier de l'IDictionary (c'est-à-dire qu'il doit réellement utiliser une clé de chaîne et une valeur d'objet). – rohancragg

+0

Cela dépend comment et quand vous préférez détecter les erreurs. Si vous êtes heureux d'y aller "bang" immédiatement quand quelqu'un essaie d'ajouter une clé non-chaîne, alors je pense que c'est un bon plan. –

+0

Donc je suppose que nous ne devrions envisager de le faire que si nous avons écrit le programme d'installation nous-mêmes ou si nous savons par ailleurs que c'est OK de supposer qu'une clé de chaîne sera utilisée ... – rohancragg

4

Depuis le programme d'installation est l'acceptation d'une IDictionary-objet, il devrait être en mesure de traiter tout Dictionnaire passé à lui. Au moins c'est mon opinion ... si je prends une interface, je dois être capable de gérer n'importe quelle implémentation.

En outre, je suggère que vous l'essayiez juste.

+0

Nous ne pouvons pas nous attendre à ce que le code existant connaisse les génériques. Il va appeler Add (objet, objet) et ma mise en œuvre attend une clé de chaîne, donc j'essaie de penser s'il y a des cas où les choses vont mal à l'exécution. – rohancragg

+0

Quoi qu'il en soit, merci Bobby. Je vais essayer cela et mettre à jour la question avec mes résultats. – rohancragg

+0

Je l'ai essayé et ça marche .... – rohancragg

Questions connexes