简体   繁体   English

c# foreach 循环无法在数组中添加文字

[英]c# foreach loop not able to add literals in an array

Firstly I know that I can't use a foreach loop in C# to add values in let's say an array... But why?首先,我知道我不能在 C# 中使用 foreach 循环在数组中添加值......但为什么呢? Why for example I can't do this为什么例如我不能这样做

int[] numbers = { 1, 4, 3, 5, 7, 9 };
foreach (int item in numbers)
{
    numbers[item] = 2;
}

Does it have something to do with the actual realisation of the foreach loop in the back-end?跟后端foreach循环的实际实现有关系吗? And how does the foreach loop exactly work? foreach 循环究竟是如何工作的? I know that it goes through the whole collection(array) but how exactly?我知道它遍历整个集合(数组),但究竟是怎样的?

You are passing in the value of an item ( your variable, item , will be the value of the array at each position in sequence, not the index ) in the array as the index.您正在传递数组中项目的值(您的变量item将是序列中每个位置的数组值,而不是索引)作为索引。 The index used there is meant to be the position of the item you are attempting to access, not the value.那里使用的索引是您尝试访问的项目的位置,而不是值。 So each iteration of the loop you are calling:因此,您正在调用的循环的每次迭代:

  • numbers[1]
  • numbers[4]
  • numbers[3]
  • numbers[5]
  • numbers[7]
  • numbers[9]

The array has 6 numbers, so when you get to numbers[7] , you are asking for a value that is not there, hence the exception.该数组有 6 个数字,因此当您到达numbers[7] ,您要求的是一个不存在的值,因此是例外。

A better method of doing what you are trying to do would be:做你想做的事情的更好方法是:

for(int i = 0; i < numbers.Length; i++)
{
    numbers[i] = 2;
}

On each iteration of this loop you would be accessing:在此循环的每次迭代中,您将访问:

  • numbers[0]
  • numbers[1]
  • numbers[2]
  • numbers[3]
  • numbers[4]
  • numbers[5]

You need to step through your code in a debugger .您需要 在调试器中逐步执行您的代码

A for statement is more like a while statement, not like a foreach . for语句更像是while语句,而不是foreach

The line int[] numbers = { 1, 4, 3, 5, 7, 9 };int[] numbers = { 1, 4, 3, 5, 7, 9 }; create this:创建这个:

numbers[0] = 1;
numbers[1] = 4;
numbers[2] = 3;
numbers[3] = 5;
numbers[4] = 7;
numbers[5] = 9;

Your foreach statement does this:您的foreach语句执行以下操作:

numbers[1] = 2;
numbers[4] = 2;
numbers[3] = 2;
numbers[5] = 2;
numbers[7] = 2; <- this line overflows your array!
numbers[9] = 2; <- and so would this.

You have to learn the difference between an array index and an array value.您必须了解数组索引和数组值之间的区别。

I'm looking at this:我在看这个:

numbers[item] = 2;

In this expression, you're using the item variable like an index , as if it had the values 1 , 2 , 3 , 4 , etc. That's not how the foreach iteration variable works for C# .在这个表达式中,您像使用索引一样使用item变量,就好像它具有值1234等。这不是 foreach 迭代变量在 C# 中的工作方式 The only language I know that does it this way is Javascript.我知道这样做的唯一语言是 Javascript。

Remember that foreach and for are not the same thing.请记住, foreachfor不是一回事。 Just about every other language, including C#, gives you the actual array values in the item variable of a foreach loop: 1 , 4 , 3 , 5 etc. Now, these are integers, so you could try to use them as indexes.几乎所有其他语言,包括 C#,都会在foreach循环的item变量中为您提供实际的数组值: 1435等。现在,这些是整数,因此您可以尝试将它们用作索引。 You can run the loop for a while like that... until you get to the value 7 .您可以像这样运行循环一段时间...直到达到值7 At this point, your array only has six values.此时,您的数组只有六个值。 You're trying to do this:你正在尝试这样做:

numbers[7] = 2;

for an array where the largest valid index you can use is 5 .对于可以使用的最大有效索引为5的数组。

This is true even taking your modification of the array into account.即使考虑到您对数组的修改,情况也是如此。 Let's look at the array after each iteration through the loop:让我们看一下循环每次迭代后的数组:

{ 1, 4, 3, 5, 7, 9 }  //initial state
{ 1, 2, 3, 5, 7, 9 }  // after 1st iteration (index 0). Value at index 0 is 1, so item as index 1 is set to 2
{ 1, 2, 2, 5, 7, 9 }  // after 2nd iteration (index 1). Value at index 1 is now 2, so item at index 2 is set to 2
{ 1, 2, 2, 5, 7, 9 }  // after 3rd iteration (index 2). Value at index 2 is now 2, so item at index 2 is set to 2
{ 1, 2, 2, 5, 7, 2 }  // after 4th iteration (index 3). Value at index 3 is 5, so item at index 5 is set to 2
// The 5th iteration (index 4). Value at index 4 is 7, which is beyond the end of the array

For the why of this... it sounds like you're used to a more dynamic language.至于为什么......听起来你已经习惯了一种更动态的语言。 Some these other languages, like php or Javascript, don't have real arrays at all in the pure computer science sense.一些其他语言,如 php 或 Javascript,在纯计算机科学意义上根本没有真正的数组 Instead, they have collection types they'll call an array, but when you get down to it are really something different.相反,它们具有称为数组的集合类型,但是当您深入了解它时,它们确实有所不同。

C# has real arrays, and real arrays have a fixed size. C#有实数数组,实数数组有固定大小。 If what you really want is a collection , C# has collections, too.如果您真正想要的是集合,C# 也有集合。 You can use List<T> objects, for example, to get an array-like collection you can append to easily.例如,您可以使用List<T>对象来获取可以轻松附加到的类似数组的集合。

For the other languages, the results vary depending on what you're talking about, but for the most permissive the result of your 5th iteration is something like this:对于其他语言,结果因您所谈论的内容而异,但对于最宽松的第 5 次迭代的结果是这样的:

{ 1, 2, 2, 5, 7, 2,  ,2 } 

Note the missing value at index 6. That kind of things leads to mistakes that slip through your tests and don't show up until run-time.请注意索引 6 处的缺失值。这种情况会导致错误从测试中溜走,直到运行时才会出现。 You also need to start wondering just how densely or sparsely the array will be filled, because the best strategy for handling these arrays can vary wildly depending on your answer... everything from just a big backing array with empty nodes that the programmer has to know about all the way to Hashtables and Dictionaries.您还需要开始考虑填充数组的密度或稀疏程度,因为处理这些数组的最佳策略可能会因您的答案而异...了解哈希表和字典的所有方式。 And, by the way, C# again has these options available to you.而且,顺便说一下,C# 再次为您提供了这些选项。

You need to create counter, in other case you trying to access item outside of array您需要创建计数器,在其他情况下,您尝试访问数组之外​​的项目

int[] numbers = new int[]{ 1, 4, 3, 5, 7, 9 };
int i = 0;
foreach (int item in numbers)
{
    numbers[i] = 2;
    i++;
}

// Print the items of the array
foreach (int item in numbers)
{
    Console.WriteLine(item);
}

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

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