C# - 元组数组是可变的,但元组列表不是。我该如何解决这个问题?
C# - Tuple arrays are mutable, but tuple lists are not. How do I get around this?
我有一组要修改的值对。我还需要从这个数组中添加和删除值,所以我使用了一个列表。当我尝试使用列表时遇到错误。
Error CS1612 - Cannot modify the return value of 'List<(int, float)>.this[int]' because it is not a variable
所以我决定进行调查。我尝试改用数组,它...工作正常吗?以下代码仅在 arr1[0].Item1 += 1;
.
上引发错误
static void Main()
{
List<(int, float)> arr1 = new List<(int, float)>() { (0, 0) };
(int, float)[] arr2 = new (int, float)[1];
arr1[0].Item1 += 1; // This line
arr2[0].Item1 += 1;
}
为什么元组数组是可变的,而列表不是?这是因为数组是可以轻松修改的简单数据块,但列表背后有很多后端使事情复杂化吗?有没有简单的方法来解决这个问题,还是我必须自己定制 class?
Why are tuple arrays mutable, but lists are not?
列表本身是可变的,但不是以您执行它的方式。请注意,这不是特定于元组的任何内容 - any 可变结构就是这种情况。
列表索引器 getter returns a value (即你的情况下的元组副本) - 所以修改该值不会修改列表中的副本。编译器试图避免您对即将被丢弃的值进行更改。数组访问 不会 这样做 - arr2[0]
指的是数组中的 变量 。 (数组实际上是变量的集合。)
如果你想改变列表,你必须获取元组,改变它,然后放回去:
var tuple = arr1[0];
tuple.Item1++;
arr1[0] = tuple;
请注意,这也解释了为什么您不能使用列表访问表达式作为 ref
参数的参数,但您可以对数组执行等效操作:
public void Method(ref int x) => x++;
public void CallMethod()
{
var list = new List<int> { 0 };
var array = new int[] { 0 };
Method(ref list[0]); // Error
Method(ref array[0]); // Valid
}
我有一组要修改的值对。我还需要从这个数组中添加和删除值,所以我使用了一个列表。当我尝试使用列表时遇到错误。
Error CS1612 - Cannot modify the return value of 'List<(int, float)>.this[int]' because it is not a variable
所以我决定进行调查。我尝试改用数组,它...工作正常吗?以下代码仅在 arr1[0].Item1 += 1;
.
static void Main()
{
List<(int, float)> arr1 = new List<(int, float)>() { (0, 0) };
(int, float)[] arr2 = new (int, float)[1];
arr1[0].Item1 += 1; // This line
arr2[0].Item1 += 1;
}
为什么元组数组是可变的,而列表不是?这是因为数组是可以轻松修改的简单数据块,但列表背后有很多后端使事情复杂化吗?有没有简单的方法来解决这个问题,还是我必须自己定制 class?
Why are tuple arrays mutable, but lists are not?
列表本身是可变的,但不是以您执行它的方式。请注意,这不是特定于元组的任何内容 - any 可变结构就是这种情况。
列表索引器 getter returns a value (即你的情况下的元组副本) - 所以修改该值不会修改列表中的副本。编译器试图避免您对即将被丢弃的值进行更改。数组访问 不会 这样做 - arr2[0]
指的是数组中的 变量 。 (数组实际上是变量的集合。)
如果你想改变列表,你必须获取元组,改变它,然后放回去:
var tuple = arr1[0];
tuple.Item1++;
arr1[0] = tuple;
请注意,这也解释了为什么您不能使用列表访问表达式作为 ref
参数的参数,但您可以对数组执行等效操作:
public void Method(ref int x) => x++;
public void CallMethod()
{
var list = new List<int> { 0 };
var array = new int[] { 0 };
Method(ref list[0]); // Error
Method(ref array[0]); // Valid
}