【问题标题】:C#: Finding and changing an element in an array of structC#:在结构数组中查找和更改元素
【发布时间】:2012-03-03 08:18:39
【问题描述】:

我有一个结构 TableRow 和一个这样的结构的数组 table

table = new TableRow[10];

现在我想查找和操作数组中结构之一的内容。
我使用 Array.Find 搜索正确的数组元素:

var tr = Array.Find( table, tRow => tRow.color == 'red' );
tr.count++;

问题是结构是值类型,因此 Find 方法返回我想要操作的结构的副本。更改此副本不会更改数组中的结构。

我似乎找不到任何方法来指示 Find 方法通过引用返回结构。

【问题讨论】:

  • 你能显示 TableRow 结构体吗?需要自定义结构类型的情况非常罕见,如果其总字段大小超过 16 字节,请考虑将其转换为类
  • …或者如果任何字段在初始化后需要更改。

标签: c# arrays struct pass-by-reference


【解决方案1】:

您无法更改 Find() 用于值类型的方式。您可以将struct 转换为class——通常我们只将struct 用于表示“单个”值的非常小的(struct 和class 有很好的指导:Chossing Between Classes and Structs

或者您可以使用FindIndex() 获取数组中的位置,然后使用它来修改字段。

var pos = Array.FindIndex(table, tRow => tRow.color == 'red');

if (pos >= 0)
{
    table[pos].count++
}

【讨论】:

  • 谢谢,詹姆斯。三个答案中最完整和最快的,所以你会得到复选标记。
  • 谢谢!当我第一次接触 C# 时,我对结构和类有很多先入为主的概念,它们是非常不同的鸟,各有优缺点。正如 Douglas 所说,由于它们的按值传递语义,它们确实往往最适合不可变值(DateTimeTimeSpan 等都是主要示例),并且因为它们只有在它们是DateTime 等)。
【解决方案2】:

您可以使用FindIndex 来获取匹配元素的从零开始的索引,然后更改它。

int i = Array.FindIndex(table, tRow => tRow.color == 'red');
table[i].count++;

但是,建议结构应该(几乎总是)是不可变的。根据@James 提供的 MSDN 链接(已添加重点):

除非类型具有以下所有特征,否则不要定义结构:

  • 它在逻辑上表示单个值,类似于原始类型(整数、双精度等)。
  • 它的实例大小小于 16 字节。
  • 它是不可变的。
  • 不必经常装箱。

既然你打算更新你的TableRow 实例的count,那么你首先不应该使用结构。在我看来,最好将其转换为一个类。

【讨论】:

  • 谢谢道格拉斯。结构应该始终是不可变的明确提示使我快速找到有关该主题的更多信息。我一定会转为上课。
【解决方案3】:

因为结构是值类型,所以您必须创建 TableRow 的新实例并用它替换所需的元素。 您可以使用 Array.FindIndex 来查找元素的索引。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 2011-06-09
    • 2013-01-21
    相关资源
    最近更新 更多