Реализация методов ForEach для многомерного массива в C #

Я работаю с System.Array и я обнаружил, что входной параметр ForEach метод public static void ForEach<T>(T[] array, Action<T> action); указывается на одномерном массиве case. Я пытаюсь обобщить это на многомерный массив.

Экспериментальная реализация

Вот экспериментальная реализация обобщенного ForEach метод.

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;
    }
}

Тестовые кейсы

Ниже приведены контрольные примеры для одномерного, двухмерного и трехмерного случаев.

//    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);
}

Результат вышеуказанных тестов:

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

Мне интересно узнать о потенциальных недостатках или рисках этой реализации.

Все предложения приветствуются.

1 ответ
1

Решение прекрасное, настолько простое, насколько могло быть, но есть лучший способ сделать к нему доступ — метод расширения.

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;
    }
}

Тогда тестовые примеры могут выглядеть так

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);

  • 2

    Хороший звонок о реализации расширений. Я бы предложил переименовать класс в ArrayExtensions, чтобы четко указать, что это класс расширений.

    — Аббас

  • @ Аббас согласен. Но что касается меня ArrayHelpers, ArrayTools, ArrayUtilities в порядке, как ArrayExtensions.

    — эспот

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *