异类字典,但键入?

时间:2008-11-27 12:32:44

标签: .net

这更像是一个学术探究,而不是一个实际问题。是否有任何语言或框架功能可以或将来允许异构类型的DCitionary,例如

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

其中myDict现在不包含两个object类型的值,而是一个string和一个double?然后,我可以使用

检索我的double
double dbl = myDict["Height"];

并期望抛出双重或异常?

请注意:名称和高度值不一定是同一个对象。

8 个答案:

答案 0 :(得分:7)

如果您的自定义集合具有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

答案 1 :(得分:1)

您可以使用Generic Dictionary<object, object>;键的对象类型和值的对象类型。 C#可以提供帮助。

答案 2 :(得分:1)

键都是字符串?然后Dictionary<string,object>可能会完成这项工作......但是当获得价值时,您需要使用object,或者您需要投射:

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

答案 3 :(得分:1)

如果类型是类,那么没有什么可以阻止你连接两者并将实例放在字典中&lt; foo,IYourInterface&gt;

答案 4 :(得分:1)

字典不是这样做的方式 你真的想要一个Person类来存储这些值。

而且,创建集合和捕获类错误要容易得多。

编辑:

因为你需要一个半强类型的词典:

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

答案 5 :(得分:0)

你有什么理由不能创建一个类/结构并将其放入列表或字典中吗?否则你可以用自己的方式包装字典类,并以这种方式设置限制。

答案 6 :(得分:0)

为什么不简单地将所有值存储为字符串,在检索它们时将其转换,并从该转换中捕获异常?

我不明白为什么你需要这样做 - 也许有必要重新设计你的程序?

答案 7 :(得分:0)

字典将包含一个字符串和一个double作为值,但double将被加框。

编译器如何验证您的要求?如何在编译时知道哪种类型的对象与每个键有关?