【问题标题】:Indexed container that holds a key value?保存键值的索引容器?
【发布时间】:2018-05-10 18:10:33
【问题描述】:

我在决定数据容器时遇到了一些问题:

我需要保存一个键值数组,这样我就可以通过索引访问数据。

我从一个开始:

static Tuple<string, string>[] kv = {
    Tuple.Create("K1", "V1"),
    Tuple.Create("K2", "V2"),
    Tuple.Create("K3", "V3"),
};

var index = 1;
Console.WriteLine(kv[index].Item1);
Console.WriteLine(kv[index].Item2);

另一方面,我可以简单地使用结构或类:

public struct KV
{            
    public string K;
    public string V;
}

static KV[] kv =
{
    new KV { K = "K1", V = "V1"  },
    // etc...
};


Console.WriteLine(kv[index].K);
Console.WriteLine(kv[index].V); 

与结构/类方法相比,使用Tuple 有什么优势吗?还是有比上述更好的容器来保存这些数据?

【问题讨论】:

  • 假设键是唯一的,这里通常使用Dictionary&lt;string, string&gt;
  • 我可能遗漏了一些东西,但是您不使用Dictionary&lt;TKey, TValue&gt; 有什么原因吗? msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx
  • 结构相对于元组的优势在于它为您提供了命名字段。随着程序复杂性的增加,如果它们是元组,则可能不清楚这些值的初衷是什么。元组可能比结构具有更小的内存占用,但如果您使用高级语言进行编程,它可能可以忽略不计。
  • @Rufus L,我需要按索引访问数据,而这对于字典来说是无法实现的 AFAIK
  • 仅供参考,使用 C# 7,您可以使用新的值元组并命名为 (string Key, string Value)[],我认为只有在数组范围有限时才更喜欢。

标签: c#


【解决方案1】:

在 C# 中创建自定义数据类型(类似于您所要求的)的常用方法是使用 classstruct

class Foo { int test; string name; }
struct Foo { int test; string name; }

var foo = new Foo() {test = 10, name = "some_name"};

您会注意到,当我们需要在类中进行大量自定义时,这非常有用 - 属性、方法、属性等。但很多时候,我们只是不需要所有的花里胡哨。我们只需要传递多个不同类型的变量

随着 .NET Framework 2.0 中 LINQ 的发布,出现了 anonymous type 类,这些类以简洁的语法提供命名但只读的属性,但这些类型仅限于在方法中使用,并且不能在方法之间传递.

var foo = new {test = 10, name = "some_name" }

在 .NET Framework 4.0 中,他们提出了 Tuple 结构。这里没有魔法,它只是一个预定义的通用结构。这个结构的变体有多达 8 个不同类型的成员。

var foo = new Tuple<int, string>(10, "some_name");

var foo = Tuple.Create(10, "some_name");

这种方法的明显限制是成员具有Item1Item2 等通用名称,因此不适合通过“长距离”传递数据。好处是它非常简洁,没有不必要的开销。

使用最新版本的 C# 7,他们正在努力将匿名类型和元组的优点结合到可以在函数之间传递的匿名元组类型(称为 ValueTuple)。事实上,它们可以通过简洁的语法隐式创建。

(test, name) Foo() {
    return Bar()
}
(test, name) Bar() {
    return (1, "new_name");
}

var allItems = new List<(int test, string name)>() {
    (1, "some_name"),
    (2, "new_name"),
}

在所有这些背景下,我强烈建议将 ValueTuple 用于作为容器传递数据的数据结构,并在您需要更多表达能力(属性、属性、方法等)

通常来说,当您的成员很少(比如少于 5 个)时,最好是 ValueType,使用 ValueTuple(即 struct)您将获得性能优势。我不建议关注这方面,除非它是非常以性能为中心的应用程序。

更新:
为确保您可以使用ValueTuple,您可能需要检查并确认一些事项。

  1. 确保您使用的是 C# 7 或更高版本(项目属性 -> 构建 -> 高级 -> 语言版本)?
  2. 确保您使用的是 .NET Framework 4.7 或更高版本(项目属性 -> 应用程序 -> 目标框架)?
  3. 如果您的 .NET Framework 版本低于 4.7,那么您可以安装 .NET Framework 版本 4.7(或更高)或安装 System.ValueTuple nuget 包。没有 using 子句来引用它。

【讨论】:

  • 我在 VS 2017 上,var allItems = new List&lt;(int test, string name)&gt;()... 无法编译。怎么做才能使它工作或我应该添加什么参考?
【解决方案2】:

使用元组有什么好处

它是内置的,您无需手动创建另一个结构/类。除此之外,它们几乎相同。

或者你可以使用KeyValuePair,它做同样的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-19
    • 2021-04-20
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    相关资源
    最近更新 更多