如何消除这些函数中的冗余代码?

How To Eliminate Redundant Code In These Functions?

出于教学目的,我编写了一些计时代码。一组代码使用冒泡排序(演示 O(n^2) 复杂度),另一组代码使用快速排序 (O(n log n))。函数签名不同;我的冒泡排序采用一个 int 数组和 returns 一个 int 数组,而快速排序采用一个 int 数组并就地修改它——void return。所以这是我为操作计时的代码:

    private delegate int[] ArrayFunc(int[] arr);
    private delegate void AlternateArrayFunc(int[] arr, int lbound, int ubound);

    private static long TimeOperation(ArrayFunc functionToTest,int[] arrayToSort, int[] correctResult) 
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        int[] resultArray = functionToTest.Invoke(arrayToSort);
        stopwatch.Stop();
        Debug.Assert(resultArray.SequenceEqual(correctResult), "Arrays do not match");
        return stopwatch.ElapsedTicks;
    }

    private static long TimeOperation(AlternateArrayFunc functionToTest, int[] arrayToSort, int[] correctResult)
    {
        var stopwatch = new System.Diagnostics.Stopwatch();
        stopwatch.Start();
        functionToTest.Invoke(arrayToSort, 0, arrayToSort.Length - 1);
        stopwatch.Stop();
        Debug.Assert(arrayToSort.SequenceEqual(correctResult), "Arrays do not match");
        return stopwatch.ElapsedTicks;
    }

我只想要一个 TimeOperation 函数,但我不太清楚如何处理这两个不同的委托。我尝试使第一个参数成为通用参数,但我无法通过委托来实现——或者至少我无法弄清楚如何做到这一点。如果我将它设为通用,那么它会在 .invoke 处犹豫不决,我真的很讨厌以这种方式保留代码,因为唯一不同的部分是我正在计时的实际功能。

关于我在这种情况下如何遵循 DRY 原则的任何建议?

您可以为快速排序创建一个与冒泡排序方法具有相同签名的附加方法:

public int[] QuickSortEntry(int[] arr)
{
    QuickSort(arr, 0, arr.Length - 1);
    return arr;
}

或者您甚至可以这样做:

ArrayFunc qSort = arr => { QuickSort(arr, 0, arr.Length - 1); return arr; };

...并将其传递到您的计时器方法中。