首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >KeyValuePair列表

KeyValuePair列表
EN

Stack Overflow用户
提问于 2011-01-26 23:07:33
回答 5查看 23.8K关注 0票数 1

为什么.NET不为List<KeyValuePair<T, U>>提供一个类

我认为在很多情况下,您需要保留一组配对。例如,

代码语言:javascript
复制
1; 2      "a"; "array"
5; 8      "b"; "browser"
1; 9      "f"; "Firefox"
8; 10     "f"; "frequency"

±la:

代码语言:javascript
复制
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;
EN

回答 5

Stack Overflow用户

发布于 2011-01-26 23:24:18

这对我来说似乎完全没有必要--仅仅因为你有一对值并不意味着它一定是键/值关系。

.NET 4引入了Tuple类型家族...除非这真的是一个键/值对,否则我会改用List<Tuple<T1, T2>> -而且我认为没有理由存在单个类型来封装该构造。

编辑:为了把这一点放到上下文中,下面是在这里使用Tuple有多“困难”,转换您的示例代码:

代码语言:javascript
复制
var myPairs = new List<Tuple<int, int>> {
    Tuple.Create(10, 8),
    Tuple.Create(5, 8),
    Tuple.Create(10, 5),
    Tuple.Create(1, 4),
};

现在元组是不可变的,所以你不能直接按照代码的最后一部分来设置值...但是组成“列表”和“值对”这两个概念的美妙之处在于,您可以很容易地编写自己的MutableTuple类型,并使用完全相同的代码……然而,如果你有一个集合类,这个集合类被硬连接到Tuple或其他类型,你就不会有那样的灵活性。

票数 9
EN

Stack Overflow用户

发布于 2011-01-26 23:22:22

为什么要止步于此?为什么不是三胞胎的列表呢?还是四胞胎?

事实是,这是你自己编写的非常简单的。编写一个从List<KeyValuePair<TKey, TValue>>派生的类,添加一个接受2个参数的Add方法。

代码语言:javascript
复制
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>一样);所以如果你想要这样做的话:

代码语言:javascript
复制
list[0].Value = 5;

...then你需要一个可变类型,类似于:

代码语言:javascript
复制
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... */ }

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

代码语言:javascript
复制
var list = new PairList<int, string>
{
    { 1, "dan" },
    { 2, "serhio" }
};

但同样,这里的重点是,这非常简单,非常琐碎,因此不值得在框架中使用自己的类型。这样看:你能在BCL中命名任何本质上只是另一种类型,但添加了一个方便的方法的类型吗?

Closing comments:您提出了以下问题:

  • 如果可以只使用List<T>数组,为什么还要引入T[]类型?
  • 如果可以只使用List<KeyValuePair<TKey, TValue>>

,为什么还要引入Dictionary<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>。老实说,对我来说,好处就是添加了一个只包装List<int>Int32List类型。

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

票数 4
EN

Stack Overflow用户

发布于 2011-01-26 23:13:14

是什么阻止了你直接使用List<KeyValuePair<T, V>>?而且,如果您了解TV,则可以在源文件的顶部为其添加别名:

代码语言:javascript
复制
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
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4806079

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档