KeyValuePair列表

时间:2011-01-26 15:07:33

标签: .net

为什么.NET没有为List<KeyValuePair<T, U>>提供类?

我认为当你需要保持一对数组时,有很多情况。例如,

1; 2      "a"; "array"
5; 8      "b"; "browser"
1; 9      "f"; "Firefox"
8; 10     "f"; "frequency"

Àla:

Pairs<int, int> myPairs;

myPairs.Add(10, 8);
myPairs.Add(5, 8);
myPairs.Add(10, 5);
myPairs.Add(1, 4);

myPairs[0].Value1 = 5;
myPairs[5].Value2 = 8;

5 个答案:

答案 0 :(得分:9)

这对我来说似乎完全没用 - 而且仅仅因为你有一对价值观并不意味着它也必然是一个关键/价值关系。

.NET 4引入了Tuple类型的系列......除非这个 是一个键/值对,否则我会使用List<Tuple<T1, T2>> - 而且我看到了没有理由存在单一类型以封装该构造。

编辑:要将其置于上下文中,这里使用Tuple来转换示例代码是多么“困难”:

var myPairs = new List<Tuple<int, int>> {
    Tuple.Create(10, 8),
    Tuple.Create(5, 8),
    Tuple.Create(10, 5),
    Tuple.Create(1, 4),
};

现在元组是不可变的,所以你不能按照代码的最后部分直接设置值......但编写两个概念“list”的美妙之处和“值对”是你可以轻松编写自己的MutableTuple类型并使用完全相同的代码...而如果你有一个集合类,它被硬连接到Tuple或其他一些类型,你不会有这种灵活性。

答案 1 :(得分:4)

为何停在那里?为什么不列出三胞胎?还是四胞胎?

事实是,写下你自己非常是微不足道的。编写一个派生自List<KeyValuePair<TKey, TValue>>的类,添加一个带有2个参数的Add方法。

public class KeyValueList<TKey, TValue> : List<KeyValuePair<TKey, TValue>>
{
    public void Add(TKey key, TValue value)
    {
        Add(new KeyValuePair<TKey, TValue>(key, value));
    }
}
砰的一声,你已经完成了。


进一步评论:请注意KeyValuePair<TKey, TValue>是一种不可变类型(在.NET 4.0中为Tuple<T1, T2>);所以,如果你想做这样的事情:

list[0].Value = 5;

...那么你需要一个可变类型,如:

public sealed class Pair<T1, T2>
{
    public T1 X { get; set; }
    public T2 Y { get; set; }
}

public class PairList<T1, T2> : List<Pair<T1, T2>>
{ /* ...same as KeyValueList<T1, T2>, basically... */ }

另请注意,这将启用良好的初始化语法:

var list = new PairList<int, string>
{
    { 1, "dan" },
    { 2, "serhio" }
};

再次,这里的要点是,这非常容易且非常简单,因此在框架中并不真正值得拥有自己的类型。以这种方式看待它:你能否在BCL中命名任何基本上只是另一种类型但只添加一个便利方法的类型?


结束评论:您提出了以下问题:

  • 为什么在使用List<T>数组时会引入T[]类型?
  • 为什么在使用Dictionary<TKey, TValue>时会引入List<KeyValuePair<TKey, TValue>>类型?

老实说,这些都是奇怪的问题。当你可以用程序代码和全局变量做所有事情时,为什么要引入OOP?为什么要在汇编中编写所有内容时引入C#,C ++甚至C等高级编程语言?

List<T>类为访问数组中的元素,维护项目数,根据需要调整数组大小等所有功能提供了有用的封装。您可以使用List<T>执行的操作与仅使用T[]可以执行的操作之间的重大差异

Dictionary<TKey, TValue>还封装了维护与唯一键关联的值集合的功能。它还为这些键提供了杀手O(1)查找时间。 Dictionary<TKey, TValue>List<KeyValuePair<TKey, TValue>>之间存在巨大差异

List<KeyValuePair<TKey, TValue>>与您提议的KeyValueList<TKey, TValue>之间的差异(正如我上面所说)实际上是零。几乎没有任何新东西被封装起来。它只是 一个List<T>。老实说,对我来说,这个好处几乎不会比添加Int32List只包含List<int>的类型更多。

没有理由将这种类型添加到BCL。

答案 2 :(得分:3)

什么阻止您直接使用List<KeyValuePair<T, V>>?而且,如果您知道TV,则可以在源文件的顶部对其进行别名:

using KeyValueList = System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<MyNS.MyKeyType, MyNS.MyValueType>>;

// in your code...
KeyValueList list = new KeyValueList();
list.Add(new KeyValuePair<MyKeyType, MyValueType>(..., ...));

答案 3 :(得分:1)

您可能正在寻找Dictionary<TKey,TValue>

  

表示键和值的集合。

Dictionary<TKey,TValue>是一个专门针对键/值对进行优化的集合。虽然您可以自由地创建List<KeyValuePair<TKey,TValue>>,但由于您无法优化对密钥的访问权限,因此您可以自行更改。

答案 4 :(得分:0)

您可以使用System.Collections.Specialized.NameValueCollection,这是一个KeyValue商店;)

这是纯粹的(string, string)映射,但是大多数关键值情况都适用于此。

或者为System.Collections.Specialized.NameObjectCollectionBase创建一个子类,以获得对象类型的特殊解决方案。