如何使用自定义枚举器避免无限递归?

6 c# recursion

我做了一个扩展方法来查找集合中连续值的数量.因为它是通用的,所以我允许调用者定义"incrementor",它是一个Func <>,它应该增加值以检查是否存在"next"值.

但是,如果调用者传递了一个不正确的递增器(即x => x),它将导致无限递归循环.有什么建议干净的方法来防止这种情况?

public static int CountConsecutive<T>(this IEnumerable<T> values, T startValue, Func<T, T> incrementor)
{
    if (values == null)
    {
        throw new ArgumentNullException("values");
    }
    if (incrementor == null)
    {
        throw new ArgumentNullException("incrementor");
    }
    var nextValue = incrementor(startValue);
    return values.Contains(nextValue)
        ? values.CountConsecutive(nextValue, incrementor) + 1
        : 1;
}
Run Code Online (Sandbox Code Playgroud)

Aus*_*nen 0

从最纯粹的意义上来说,这是对停止问题的尝试,并且是不可判定的。对于除了最简单的情况之外的所有情况,您都必须信任那些调用您的方法的人。

就像其他人所展示的那样,您可以进行简单的相等检查以表明下一个值是不同的。存储每次访问的内容都T可以,但最终您将不得不担心内存问题。

顺便说一句,这里有一个很容易实现的 StackOverflowException,因此您必须警惕任何包含大量连续值的数据集。

var x = Enumerable.Range(1, 100000).CountConsecutive(1, x => x+1);
Run Code Online (Sandbox Code Playgroud)