简体   繁体   English

如何在 C# 中创建一个包含不同类型的字典

[英]How do I create a Dictionary that holds different types in C#

I need some sort of way to store key/value pairs where the value can be of different types.我需要某种方式来存储键/值对,其中值可以是不同类型。

So I like to do:所以我喜欢这样做:

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

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

And later retrieve the values with:然后使用以下方法检索值:

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

How should a Storage like this look like?这样的存储应该是什么样子的? Thanks, Erik谢谢,埃里克

Well, you could use Dictionary<string, dynamic> in C# 4 / .NET 4 - but other than that, you can't do it with exactly the code shown because there's no type which is implicitly convertible to int , string and double .好吧,您可以在 C# 4 / .NET 4 中使用Dictionary<string, dynamic> - 但除此之外,您不能完全使用显示的代码来执行此操作,因为没有可以隐式转换为intstringdouble (You could write your own one, but you'd have to list each type separately.) (您可以自己编写一个,但您必须分别列出每种类型。)

You could use Dictionary<string, object> but then you'd need to cast the results:您可以使用Dictionary<string, object>但随后您需要转换结果:

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

Alternatively, you could make the Get method generic:或者,您可以使Get方法通用:

int a = Storage.Get<int>("age");
// etc

You could declare a Dictionary containing just the type object and then cast your results;可以声明一个只包含类型object的字典,然后转换你的结果; .eg 。例如

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

However, this isn't that elegant.然而,这并不是那么优雅。 If you know you are always going to be storing age, name, bmi I would create an object to encapsulate those and store that instead.如果你知道你总是要存储年龄、姓名、体重,我会创建一个对象来封装这些并存储它们。 Eg例如

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

And then use that insead of the Dictionary... eg然后使用字典的 insead ......例如

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

int age = person1.Age;

etc.等等。

Why not use:为什么不使用:

Dictionary<string, object>

You can create an extension method to cast them when you get them:你可以创建一个扩展方法来在你得到它们时转换它们:

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

Given that you don't want a strongly typed data collection then I would have thought a HashTable would be suitable for your situation.鉴于您不想要强类型数据集合,那么我会认为HashTable适合您的情况。 You could create an Extention method for this also, like another poster suggested for the Dictionary implementation.您也可以为此创建一个扩展方法,就像为 Dictionary 实现建议的另一张海报一样。

Eg例如

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

Your code would then look like:您的代码将如下所示:

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");
Dictionary<string, object>

maybe it is an old question, but I am addressing the guys who come here to find the answer也许这是一个老问题,但我正在向来这里寻找答案的人讲话

if the value is not a fixed type one of the choices is using Hashtable please look at the implementation of both Dictionary and Hashtable如果值不是固定类型的选择之一是使用Hashtable请查看 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 { ... }

as it gets more clear from above code snippets, both implement literally the same interfaces but in Hashtable there is no type on both key & value since both of them considered to be intrinsically objects, for example you can see from add method in Hashtable:从上面的代码片段中可以更清楚地看出,两者都实现了字面上相同的接口,但在 Hashtable 中,键和值都没有类型,因为它们都被认为是本质上的对象,例如,您可以从 Hashtable 中的 add 方法中看到:

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

so for the cases of not having fixed keys and/or values, I recommend using Hashtable, therefore you don't need to add extra extension methods or override default behavior of a dictionary any more.因此,对于没有固定键和/或值的情况,我建议使用 Hashtable,因此您不再需要添加额外的扩展方法或覆盖字典的默认行为。

You can use a Dictionary<string,object> and then you can put anything you want into it.你可以使用Dictionary<string,object>然后你可以把任何你想要的东西放进去。 You would have to cast the results to the right type when you get them out though.但是,当您将它们取出时,您必须将结果转换为正确的类型。

Looking at your example though you might want to consider whether a simple class to store the data might be more what you want and allow better type safety.看看你的例子,虽然你可能想考虑一个简单的类来存储数据是否可能更符合你的需求并允许更好的类型安全。 It depends on whether you have a limited set of things to put in the class or if you do need the potentially unlimited/unknown storage of a dictionary.这取决于您是否有一组有限的东西可以放入类中,或者您是否确实需要字典的潜在无限/未知存储。

Dictionary is clearly the quickest solution.字典显然是最快的解决方案。

Another way could be to store a custom class in which you could store the actual value and the information regarding its type另一种方法是存储一个自定义类,您可以在其中存储实际值和有关其类型的信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM