Гетерогенный словарь, но напечатан?
Это скорее академический вопрос, чем практический вопрос. Существуют ли какие-либо языковые или каркасные функции, которые могут или позволят в будущем использовать гетерогенный типизированный 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"];
Если типы являются классами, ничто не мешает вам взаимодействовать и помещать экземпляры в словарь
Словарь будет содержать строку и двойное значение, но двойное будет в штучной упаковке.
Как компилятор может проверить то, что вы спрашиваете? Как он мог знать во время компиляции, какой тип объекта относится к каждому ключу?
По какой-то причине вы не можете создать класс / структуру и поместить это в список или словарь? В противном случае вы можете просто обернуть словарный класс своим собственным и установить ограничения таким образом.
Почему бы просто не сохранить все значения в виде строк, преобразовать их при извлечении и отловить исключения из этого преобразования?
Я не понимаю, почему вам нужно так поступать - может быть, вам нужен редизайн вашей программы?