如何在C#中创建包含不同类型的Dictionary

时间:2010-11-05 11:15:53

标签: c# dictionary hashtable

我需要某种方式来存储键/值对,其中值可以是不同类型。

所以我喜欢这样做:

 int i = 12;
 string s = "test";
 double x = 24.1;

 Storage.Add("age", i);
 Storage.Add("name", s);
 Storage.Add("bmi", x);

然后用以下方法检索值:

 int a = Storage.Get("age");
 string b = Storage.Get("name");
 double c = Storage.Get("bmi");

这样的存储应该如何? 谢谢, 埃里克

8 个答案:

答案 0 :(得分:65)

好吧,您可以在C#4 / .NET 4中使用Dictionary<string, dynamic> - 但除此之外,您无法使用所显示的代码完成此操作,因为没有可隐式转换为{{1}的类型},intstring。 (您可以自己编写一个,但必须单独列出每种类型。)

你可以使用double但是你需要投射结果:

Dictionary<string, object>

或者,您可以将int a = (int) Storage.Get("age"); string b = (string) Storage.Get("name"); double c = (double) Storage.Get("bmi"); 方法设为通用:

Get

答案 1 :(得分:23)

可以声明一个只包含类型object的词典,然后投射你的结果; .e.g。

Dictionary<string, object> storage = new Dictionary<string,object>();

storage.Add("age", 12);
storage.Add("name", "test");
storage.Add("bmi", 24.1);

int a = (int)storage["age"];
string b = (string)storage["name"];
double c = (double)storage["bmi"];

然而,这不是那么优雅。如果你知道你总是要存储age,name,bmi我会创建一个对象来封装它们并存储它。 E.g。

public class PersonInfo
{
    public int Age { get; set; }
    public string Name { get; set; }
    public double Bmi { get; set; }
}

然后使用字典中的那个内容......例如

PersonInfo person1 = new PersonInfo { Name = "test", Age = 32, Bmi = 25.01 };

int age = person1.Age;

答案 2 :(得分:7)

为什么不使用:

Dictionary<string, object>

您可以创建一个扩展方法,以便在获取它们时强制转换它们:

public static class DictionaryExcetions
{
    public static T Get<T>(this Dictionary<string, object> instance, string name)
    {
        return (T)instance[name];
    }

}

var age = dictionary.Get<int>("age");

答案 3 :(得分:2)

Dictionary<string, object>

答案 4 :(得分:2)

鉴于您不想要强类型数据集合,我认为HashTable适合您的情况。您也可以为此创建一个Extention方法,就像为Dictionary实现建议的另一张海报一样。

E.g。

public static class StorageExtentions
{
    public static T Get<T>(this Hashtable table, object key)
    {
        return (T) table[key];
    }
}

您的代码将如下所示:

int i = 12;
string s = "test";
double x = 24.1;
Hashtable Storage = new Hashtable();
Storage.Add("age", i);
Storage.Add("name", s);
Storage.Add("bmi", x);
int a = Storage.Get<int>("age");
string b = Storage.Get<string>("name");
double c = Storage.Get<double>("bmi");

答案 5 :(得分:1)

您可以使用Dictionary<string,object>然后将任何内容放入其中。当你把结果拿出来时,你必须将结果转换为正确的类型。

查看您的示例,但您可能想要考虑一个用于存储数据的简单类是否更符合您的要求,并允许更好的类型安全性。这取决于你是否有一组有限的东西要放在课堂上,或者你是否确实需要字典的潜在无限/未知存储。

答案 6 :(得分:1)

也许这是一个古老的问题,但我正在向那些来这里寻找答案的人致意

如果该值不是固定类型,则其中之一是使用哈希表 请看一下Dictionary和Hashtable的实现

    public class Dictionary<TKey, TValue> : ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable, IDictionary<TKey, TValue>, IReadOnlyCollection<KeyValuePair<TKey, TValue>>, IReadOnlyDictionary<TKey, TValue>, ICollection, IDictionary, IDeserializationCallback, ISerializable
     {
              ... 
     }

public class Hashtable : ICollection, IEnumerable, IDictionary, ISerializable, IDeserializationCallback, ICloneable
  {
   ...
  }

从上面的代码片段可以清楚地看到,它们都实现了相同的接口,但是在Hashtable中,键和值都没有类型,因为它们都被视为本质上的对象,例如,您可以从add方法中看到哈希表:

public virtual void Add(object key, object value);

因此,对于键和/或值不固定的情况,我建议使用Hashtable,因此您完全不需要添加额外的扩展方法或覆盖默认行为。

答案 7 :(得分:0)

词典显然是最快的解决方案。

另一种方法是存储一个自定义类,您可以在其中存储实际值和有关其类型的信息