c# 中的这个 foreach 是怎么回事?

发布于 2024-12-12 14:24:45 字数 314 浏览 1 评论 0 原文

(编辑:代码稍微整洁。)

像这样使用 foreach 效果很好。

var a = new List<Vector2>();

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

然而,以下内容会导致“方法‘ForEach’没有重载需要 1 个参数”。

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

a.ForEach(delegate(byte b) {
    b = 1; });

(edit: Slight tidy of the code.)

Using foreach like this works fine.

var a = new List<Vector2>();

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

The following however causes "No overload for method 'ForEach' takes 1 arguments".

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

a.ForEach(delegate(byte b) {
    b = 1; });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

╭⌒浅淡时光〆 2024-12-19 14:24:47

您已对数组使用了 List.ForEach() 方法的语法,但 Array.ForEach() 语法是:

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

一个重要的一点是数组应该是一个-维以便在Array.ForEach()中使用它。考虑到这一点,我建议使用简单的 for 循环

// 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++)             

You've used syntax of List.ForEach() method for the array, but Array.ForEach() syntax is:

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

One important point that array should be one-dimensional in order to use it in Array.ForEach(). Considering this I would suggest using simple for loop

// 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++)             
风苍溪 2024-12-19 14:24:47

我不知道采用多维数组的 ForEach 方法。
如果你想要一个,我想你必须自己创建它。

操作方法如下:

    private static void ForEach<T>(T[, ,] a, Action<T> 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>(T[, ,] a, Action<T> action)
    {
        foreach (var item in a)
        {
            action(item);
        }
    }
}

另外,Array 版本中的 ForEach 方法不是实例方法,而是 statis 方法。你这样称呼它:

Array.ForEach(array, delegate);

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.

Here is how to do it:

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

Sample program, using the new ForEach method:

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>(T[, ,] a, Action<T> action)
    {
        foreach (var item in a)
        {
            action(item);
        }
    }
}

Also, the ForEach method in the Array version, is not an instance method, it is statis method. You call it like this:

Array.ForEach(array, delegate);
别挽留 2024-12-19 14:24:47

原始数组的实例方法比通用集合少得多,因为它们不是模板化的。这些方法(例如 ForEach()Sort())通常作为静态方法实现,这些方法本身就是模板化的。

在这种情况下,Array.Foreach(a, action) 将为数组完成任务。

当然,经典的 foreach(var b in a) 对于 List 和 Array 都适用,因为它只需要一个枚举器。

但是:

  1. 我不确定如何循环多维数组。
  2. 您的作业 (b=1) 将不起作用。因为您收到的是一个值,而不是一个引用。

raw arrays have much less instance methods than generic collections because they are not templated. These methods, such as ForEach() or Sort() are usually implemented as static methods which are themselves templated.

In this case, Array.Foreach(a, action) will do the trick for the array.

Of course, the classical foreach(var b in a) would work for both List and Array since it only requires an enumerator.

However:

  1. I'm not sure how you'd loop over a multidimensional array.
  2. Your assignment (b=1) won't work. Because you receive a value, not a reference.
瞎闹 2024-12-19 14:24:47

List 有第一个实例方法。数组则不然。

List has the first instance method. Arrays do not.

心碎的声音 2024-12-19 14:24:46

我建议您只使用普通的 foreach 循环来转换数据。您使用的方法仅存在于 List 实现中,而不存在于数组中。

使用 foreach 方法实际上不会给你带来任何好处,除非由于某种原因你想在方法链中进行数据突变。在这种情况下,您也可以为 IEnumerable 编写自己的扩展方法。不过,我建议不要这样做。

有一个单独的 foreach 循环可以让读者清楚地知道数据正在发生变化。它还消除了为循环的每次迭代调用委托的开销。无论集合类型如何,只要它是 IEnumerable ,它都可以工作(不完全正确,您可以编写自己的枚举器和枚举,但这是一个不同的问题)。

如果您只想进行数据转换(即投影等),那么请使用 LINQ。

另请记住,对于数组,您将获得字节的副本而不是引用。您将仅修改该字节而不是原始字节。这是一个输出示例:

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

正如您所看到的,lambda 中的数字 += 1 没有任何效果。事实上,如果您在正常的 foreach 循环中尝试这样做,您会收到编译器错误。

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<T> 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<T>. I would recommend against that, though.

Having a separate foreach loop makes it clear to the reader that data mutation is occurring. It also removes the overhead of calling a delegate for each iteration of the loop. It will also work regardless of the collection type as long as it is an IEnumerable (not entirely true, you can write your own enumerators and enumerables, but that's a different question).

If you're looking to just do data transformations (i.e. projections and the like) then use LINQ.

Also keep in mind that with the array, you're getting a copy of the byte not a reference. You'll be modifying just that byte not the original. Here's an example with the output:

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

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

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

Which yields the output:

1
2
3
4
5

As you can see, the number += 1 in the lambda had no effect. In fact, if you tried this in a normal foreach loop, you would get a compiler error.

如痴如狂 2024-12-19 14:24:46

您正在使用两个不同的 ForEach

Array.ForEachbyte[,,] 示例(尽管您使用不正确)和 List<...> 示例中的 rel="nofollow">List.ForEach

You're using two different ForEach'es.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文