Що відбувається з цим foreach в c #?

(редагування: незначна охайність коду.)

Використання foreach як це працює нормально.

var a = new List();

a.ForEach(delegate(Vector2 b) {
    b.Normalize(); });

Наступне, однак, призводить до того, що "Ні перевантаження для методу" ForEach "не містить 1 аргументу".

byte[,,] a = new byte[2, 10, 10];

a.ForEach(delegate(byte b) {
    b = 1; });
5
Якщо вам не потрібен делегат, слід використовувати звичайний цикл foreach , а не метод ForEach() .
додано Автор svick, джерело

6 Відповіді

Ви використовуєте два різних ForEach 'ес.

Array.ForEach in the byte[,,] example (though you're using it incorrectly) and List.ForEach in the List<...> example.

2
додано

I would recommend you just use a normal foreach loop to transform the data. You're using a method that exists only on the List implementation, but not on arrays.

Using a method for foreach really gains you nothing, unless for some reason you were wanting to do data mutation in a method chain. In that case, you may as well write your own extension method for IEnumerable. I would recommend against that, though.

Окремі цикли foreach дають читачеві зрозуміти, що відбувається мутація даних. Він також видаляє накладні витрати на виклик делегата для кожної ітерації циклу. Він буде працювати незалежно від типу колекції, якщо він є IEnumerable (не цілком істинним, ви можете писати свої власні переліки та перелік, але це інше питання).

Якщо ви хочете просто здійснити перетворення даних (тобто проекції тощо), використовуйте LINQ.

Також майте на увазі, що за допомогою масиву ви отримуєте копію byte , а не посилання. Ви будете змінювати лише те, що byte не оригінал. Ось приклад з виходом:

int[] numbers = new int[] { 1, 2, 3, 4, 5 };

Array.ForEach(numbers, number => number += 1);

foreach(int number in numbers)
{
    Console.WriteLine(number);
}

Який дає результат:

1   2   3   4   5

Як ви бачите, число π = 1 в лямбда не мав ефекту. Фактично, якщо ви спробували це в звичайному циклі foreach , ви отримаєте помилку компілятора.

2
додано

Ви використали синтаксис методу List.ForEach() для масиву, але синтаксис Array.ForEach() :

public static void ForEach(
    T[] array,
    Action action
)

Один важливий момент, що масив має бути одномірним , щоб використовувати його в Array.ForEach() . З огляду на це я запропонував би скористатися простим для циклом

// first dimension
for (int index = 0; index < bytesArray.GetLength(0); index++)             

// second dimension
for (int index = 0; index < bytesArray.GetLength(1); index++)             

// third dimension
for (int index = 0; index < bytesArray.GetLength(2); index++)             
1
додано

I don't know of a ForEach method that takes multi-dimensional arrays. If you want one, i think you will have to create it yourself.

Ось як це зробити:

    private static void ForEach(T[, ,] a, Action action)
    {
        foreach (var item in a)
        {
            action(item);
        }
    }

Приклад програми, використовуючи новий метод ForEach:

static class Program
{
    static void Main()
    {
        byte[, ,] a = new byte[2, 10, 10];

        ForEach(a, delegate(byte b)
        {
            Console.WriteLine(b);
        });
    }
    private static void ForEach(T[, ,] a, Action action)
    {
        foreach (var item in a)
        {
            action(item);
        }
    }
}

Крім того, метод ForEach в версії Array не є методом екземпляра, це метод статистики. Ви називаєте це таким:

Array.ForEach(array, delegate);
1
додано

сирі масиви мають набагато менше методів екземпляра, ніж загальні колекції, оскільки вони не шаблоновані. Ці методи, такі як ForEach() або Sort() зазвичай реалізуються як статичні методи, які самі шаблонні.

В цьому випадку, Array.Foreach (а, дія) робитиме трюк для масиву.

Звичайно, класичний foreach (var b in a) буде працювати як для списку, так і для масиву, оскільки він вимагає лише переліку.

Однак:

  1. Я не впевнений, як би ви поспілкувалися над багатовимірним масивом.
  2. Ваше завдання (b = 1) не буде працювати. Оскільки ви отримуєте значення, а не довідку.
0
додано

List has the first instance method. Arrays do not.

0
додано
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug