简体   繁体   English

是否可以通过在 C# 中使用 foreach 的引用来迭代 int 数组

[英]is it possible to iterate int array by reference with foreach in C#

Is it possible to iterate an int array by reference in a C# foreach loop?是否可以在 C# foreach 循环中通过引用迭代 int 数组?

I mean something like this:我的意思是这样的:

 int[] tab = new int[5];
 foreach (ref int i in tab)
 {
     i=5;
 }

thanks谢谢

Is it possible to iterate an int array by reference in a C# foreach loop?是否可以在 C# foreach 循环中通过引用迭代 int 数组?

No, foreach loop in C# is not designed to make changes to the collection it iterates.不,C# 中的foreach循环并非旨在对其迭代的集合进行更改。 It uses a readonly local variable that cannot be used as an assignment target.它使用一个不能用作赋值目标的readonly局部变量。

Still you can use for loop to do it :您仍然可以使用for循环来做到这一点:

var list = new List<MyClass>();

for(var i = 0; i < list.Count; i++)
{
   list[i] = new MyClass();
}

Or use LINQ :或使用 LINQ :

list = list.Select(e => new MyClass()).ToList(); // note that this will create a copy of list

Since C# 7.3, it works, but you need to cast the array as a Span.从 C# 7.3 开始,它可以工作,但您需要将数组转换为 Span。

int[] tab = new int[5];

foreach (ref int i in tab.AsSpan()) {
    i = 5;
}

Console.WriteLine(tab.Sum()); // 25

Tested on Net Core 3.1 and Net 5.在 Net Core 3.1 和 Net 5 上测试。

No, a foreach loop will not allow the loop variable to reference another variable.不, foreach循环不允许循环变量引用另一个变量。 It will always copy the value out of the sequence and into a new variable.它总是将值从序列中复制到一个新变量中。 To do what you're looking to do you'd need to use some structure other than a foreach loop.要完成您想要做的事情,您需要使用除foreach循环之外的其他结构。 While technically you could write your own ForEach method accepting a lambda where the parameter is a reference to an item in an array, the result...probably isn't worth it.虽然从技术上讲,您可以编写自己的ForEach方法接受一个 lambda,其中参数是对数组中项目的引用,但结果......可能不值得。

public delegate void ReferenceAction<T>(ref T param);
public static void ForEach<T>(T[] source, ReferenceAction<T> action)
{
    for (int i = 0; i < source.Length; i++)
        action(ref source[i]);
}

int[] tab = new int[5];
ForEach(tab, (ref int n) => n = 5);

There are almost certainly going to be better ways of accomplishing what you're trying to do without actually having a loop where the loop variable is a reference.几乎肯定会有更好的方法来完成您想要做的事情,而无需实际使用循环变量作为引用的循环。

Yes, that is possible in the exact same syntax as proposed in the question.是的,这与问题中提出的语法完全相同。

From Microsoft docs: Beginning with C# 7.3, if the enumerator's Current property returns a reference return value (ref T where T is the type of the collection element), you can declare the iteration variable with the ref or ref readonly modifier.来自 Microsoft 文档:从 C# 7.3 开始,如果枚举器的 Current 属性返回引用返回值(ref T,其中 T 是集合元素的类型),您可以使用 ref 或 ref readonly 修饰符声明迭代变量。

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in

Example:示例:

int val = 0;
int[] tab = new int[5];

foreach (ref int i in tab) {
    i = val++;
}

foreach (ref readonly var j in tab) {
    Console.WriteLine(j);
}

Output:输出:

0
1
2
3
4

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM