2009-10-29 3 views
3

AssemblyInstaller.Install ожидает System.Collections.IDictionary.Можно ли использовать общий словарь как параметр для ожидающего IDictionary

Я прав, чтобы быть «аллергическим» на использование не общих коллекций, таких как Hashtable, или я должен пережить себя ?!

например.

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); 
     } 
    } 
} 

Кроме того, компилятор не имеют проблем с этим decalration:

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

Но будет ничего плохого произойти во время выполнения, если кто-то использует что-то другое, чем строки в качестве ключей?


Update [отражатель на помощь]

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

Подтвердив, что говорит Джон, словарь реализует IDictionary следующим образом:

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

... так что при проверке ключа его будет генерировать исключение, если тип ключа не совпадает с типом, который используется при объявлении конкретной специализации общего словаря (а также для ty ре значения):

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

ответ

2

Это работает, потому что Dictionary<TKey, TValue> реализует IDictionary - но это действительно произойдет сбой во время выполнения, если кто-то называет IDictionary.Add(object, object) с ключом нестроковой - вы получите ArgumentException.

Обратите внимание, что интерфейс сам IDictionary<TKey, TValue> не распространяется IDictionary - это только то, что Dictionary<TKey, TValue> реализация также реализует IDictionary.

+0

Хорошо, приятно знать, спасибо. Но каково ваше мнение о том, лучше ли мне предпочесть словарь over HashTable? По крайней мере, таким образом я лучше общаюсь с тем, что я (теперь знаю) является требованием этого конкретного использования IDictionary (то есть, он должен фактически использовать строковый ключ и значение объекта). – rohancragg

+0

Это зависит от того, как и когда вы предпочитаете обнаруживать ошибки. Если вы счастливы, что он сразу же «взломает», когда кто-то пытается добавить нестрочный ключ, я думаю, что это хороший план. –

+0

Итак, я думаю, мы должны рассматривать это только в том случае, если мы сами сами написали установщика или иначе знаем, что можно предположить, что будет использоваться строковый ключ ... – rohancragg

4

Поскольку установщик принимает к IDictionary-Object, он должен быть в состоянии иметь дело с любым словарем перешедшего к нему. По крайней мере, это мое мнение ... если я возьму интерфейс, мне нужно, чтобы у него была возможность реализовать его.

Кроме того, я предлагаю вам просто попробовать.

+0

Мы не можем ожидать, что устаревший код будет знать о дженериках. Он будет вызывать Add (object, object), и моя реализация ожидает строковый ключ, поэтому я пытаюсь подумать, есть ли случаи, когда во время выполнения ситуация будет плохой. – rohancragg

+0

В любом случае, спасибо Бобби. Я попробую это и обновить вопрос с моими результатами. – rohancragg

+0

Я пробовал, и он работает .... – rohancragg

Смежные вопросы