Гетерогенный словарь, но напечатан?

Это скорее академический вопрос, чем практический вопрос. Существуют ли какие-либо языковые или каркасные функции, которые могут или позволят в будущем использовать гетерогенный типизированный dcitionary, например

myDict.Add("Name", "Bill"); 
myDict.Add("Height", 1.2); 

где myDict теперь содержит не два object типы как значения, но один string и один double? Я мог бы тогда получить мой double с

double dbl = myDict["Height"];

и ожидать двойного или исключения?

Обратите внимание: значения Name и Height не обязательно относятся к одному и тому же объекту.

8 ответов

Решение

Только так вы сможете сделать это, если у вас есть настраиваемая коллекция с общими перегрузками для методов Add и Get. Но это будет означать, что вы можете попросить неверный тип при чтении ключа, так что это не даст вам много (если вообще что-нибудь), если вы сами выполняете приведение при вызове метода Get.

Однако, если вы можете вставить общий тип в ключ, это может сработать. Нечто подобное (непроверенный код здесь)

sealed class MyDictionaryKey<T>
{
}

class MyDictionary
{
    private Dictionary<object, object> dictionary = new Dictionary<object, object>();

    public void Add<T>(MyDictionaryKey<T> key, T value)
    {
        dictionary.Add(key, value);
    }

    public bool TryGetValue<T>(MyDictionaryKey<T> key, out T value)
    {
      object objValue;
      if (dictionary.TryGetValue(key, out objValue))
      {
        value = (T)objValue;
        return true;
      }
      value = default(T);
      return false;
    }

    public T Get<T>(MyDictionaryKey<T> key)
    {
      T value;
      if (!TryGetValue(key, out value))
         throw new KeyNotFoundException();
      return value;
    }
}

Затем вы можете определить ваши ключи как:

static readonly MyDictionaryKey<string> NameKey = new MyDictionaryKey<string>();
static readonly MyDictionaryKey<double> HeightKey = new MyDictionaryKey<double>();

и использовать его как

var myDict = new MyDictionary();
myDict.Add(NameKey, "Bill"); // this will take a string
myDict.Add(HeightKey , 1.2); // this will take a double

string name = myDict.Get(NameKey); // will return a string
double height = myDict.Get(HeightKey); // will return a double

Вы можете использовать Generic Dictionary<object, object>; тип объекта для ключа и тип объекта для значения. C# может помочь.

Словарь не способ сделать это.
Вы действительно хотите класс Person для хранения этих значений.

И гораздо проще как создавать коллекции, так и отлавливать ошибки с помощью классов.

РЕДАКТИРОВАТЬ:

Так как вам нужен полустрочный тип слова dict:

public class CustomDictionary : Dictionary<string,object>
{
    public T GetTyped<T>(string key) where T : IConvertible
    {
        return (T)Convert.ChangeType(base[key], typeof (T));
    }
}

Использование:

CustomDictionary dictionary = new CustomDictionary();

dictionary.Add("Test",1.2);

var d = dictionary.GetTyped<double>("Test");

Ключи все строки? затем Dictionary<string,object> вероятно, сделает работу... но когда вы получаете значения, вам придется либо использовать objectили вам нужно будет разыграть:

double dbl = (double)myDict["Height"];
object height = myDict["Height"];

Если типы являются классами, ничто не мешает вам взаимодействовать и помещать экземпляры в словарь

Словарь будет содержать строку и двойное значение, но двойное будет в штучной упаковке.

Как компилятор может проверить то, что вы спрашиваете? Как он мог знать во время компиляции, какой тип объекта относится к каждому ключу?

По какой-то причине вы не можете создать класс / структуру и поместить это в список или словарь? В противном случае вы можете просто обернуть словарный класс своим собственным и установить ограничения таким образом.

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

Я не понимаю, почему вам нужно так поступать - может быть, вам нужен редизайн вашей программы?

Другие вопросы по тегам