2
\$\begingroup\$

I am working with System.Array and I found that the input parameter of ForEach method public static void ForEach<T>(T[] array, Action<T> action); is specified on one dimensional array case. I am trying to generalize this to multidimensional array.

The experimental implementation

Here's the experimental implementation of generalized ForEach method.

class ArrayHelpers
{
 public static void ForEach<T>(Array array, in Action<T> action)
 where T : unmanaged
 {
 if (ReferenceEquals(array, null))
 {
 throw new ArgumentNullException(nameof(array));
 }
 if (ReferenceEquals(action, null))
 {
 throw new ArgumentNullException(nameof(action));
 }
 foreach (T item in array)
 {
 action.Invoke(item);
 }
 return;
 }
}

Test cases

The Test cases for one dimensional case, two dimensional case and three dimensional case are as below.

// One dimensional case
Console.WriteLine("One dimensional case");
int[] test = new int[] { 1, 2, 3, 4 };
ArrayHelpers.ForEach<int>(test, ShowSquares);
// two dimensional case
Console.WriteLine("Two dimensional case");
int[,] test2 = { { 0, 1 }, { 2, 3 } };
ArrayHelpers.ForEach<int>(test2, ShowSquares);
// three dimensional case
Console.WriteLine("Three dimensional case");
int[,,] test3 = { { { 0, 1 }, { 2, 3 } }, { { 0, 1 }, { 2, 3 } } };
ArrayHelpers.ForEach<int>(test3, ShowSquares);
/// <summary>
/// Reference: https://docs.microsoft.com/en-us/dotnet/api/system.array.foreach?view=net-5.0
/// </summary>
/// <param name="val">The input value for displaying and calculating square result</param>
private static void ShowSquares(int val)
{
 Console.WriteLine("{0:d} squared = {1:d}", val, val * val);
}

The output of the above tests:

One dimensional case
1 squared = 1
2 squared = 4
3 squared = 9
4 squared = 16
Two dimensional case
0 squared = 0
1 squared = 1
2 squared = 4
3 squared = 9
Three dimensional case
0 squared = 0
1 squared = 1
2 squared = 4
3 squared = 9
0 squared = 0
1 squared = 1
2 squared = 4
3 squared = 9

I am wondering the things about the potential drawback or risks of this implementation.

All suggestions are welcome.

asked Mar 3, 2021 at 19:39
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The solution is fine as it easy as it could be but there's a better way to make the access to it - extension method.

public static class ArrayHelpers
{
 public static void ForEach<T>(this Array array, in Action<T> action)
 {
 if (ReferenceEquals(array, null))
 {
 throw new ArgumentNullException(nameof(array));
 }
 if (ReferenceEquals(action, null))
 {
 throw new ArgumentNullException(nameof(action));
 }
 foreach (T item in array)
 {
 action.Invoke(item);
 }
 return;
 }
}

Then the test cases can look like this

Console.WriteLine("One dimensional case");
int[] test = new int[] { 1, 2, 3, 4 };
test.ForEach<int>(ShowSquares);
Console.WriteLine("Two dimensional case");
int[,] test2 = { { 0, 1 }, { 2, 3 } };
test2.ForEach<int>(ShowSquares);
Console.WriteLine("Three dimensional case");
int[,,] test3 = { { { 0, 1 }, { 2, 3 } }, { { 0, 1 }, { 2, 3 } } };
test3.ForEach<int>(ShowSquares);
answered Mar 3, 2021 at 20:50
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Good call on the extensions implementation. I would suggest to rename the class to ArrayExtensions to clearly indicate the fact that is an extensions class. \$\endgroup\$ Commented Mar 4, 2021 at 6:43
  • \$\begingroup\$ @Abbas agree. But as for me ArrayHelpers, ArrayTools, ArrayUtilities are fine as ArrayExtensions. \$\endgroup\$ Commented Mar 4, 2021 at 7:04

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.