无法评估表达式c#

时间:2017-05-10 05:50:04

标签: c#

我在var okColors = colors.ToArray();

收到以下错误
  

无法计算表达式,因为当前线程处于堆栈溢出状态。

你可以帮忙吗?

    private Color GetRandomColor()
    {
        Random randomGen = new Random();
        Color randomColor = Color.Red;

        KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));
        KnownColor[] badColors = { KnownColor.AliceBlue };
        IEnumerable<KnownColor> colors = names.Except(badColors);

        var okColors = colors.ToArray();

        KnownColor randomColorName = okColors[randomGen.Next(okColors.Length)];
        randomColor = Color.FromKnownColor(randomColorName);
        if (!ColorsList.Contains(randomColor) && !randomColor.Name.Contains("Light"))
            ColorsList.Add(randomColor);
        else
            GetRandomColor();
        return randomColor;
    }

4 个答案:

答案 0 :(得分:2)

您的代码抛出StackOverflowException,当它发生时,调试器无法再评估导致您看到错误的任何变量。

为什么代码有StackOverflowException

  • 代码使用错误的方式生成随机数,并以足够的调用结束相同的数字。正确的方式 - How do I generate a random int number in C#? - 使用静态Random实例。
  • 结果检查.Contains经常失败,代码基本上变成无限递归:

    private Color GetRandomColor()
    {
      if (true) return GetRandomColor();
    }
    

补充阅读:How do I prevent and/or handle a StackOverflowException?

答案 1 :(得分:2)

您必须为每个递归调用使用相同的Random 实例,不要在每个函数调用中创建一个新实例。如果在每次调用函数时都在函数中创建了一个新的Random实例,那么您可能会得到相同的值而不是您想象的随机值。

您可能需要查看以下another thread

  

randomNumber每次创建一个新的Random实例...   turn根据当前值创建一个新的伪随机数生成器   时间......不会像你想象的那样经常改变。

在链接的帖子中,Jon Skeet也建议不要使用静态随机变量。

  

重复使用相同的Random实例...但不要“修复”它   创建一个静态随机变量。无论如何,这都行不通   长期,因为Random不是线程安全的。

一个选项可以是将一个Random实例作为参数传递给函数,这样可以确保在递归链中传递相同的Random实例:

private Color GetRandomColor(Random randomGen = new Random())
{
    Color randomColor = Color.Red;

    KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));
    KnownColor[] badColors = { KnownColor.AliceBlue };
    IEnumerable<KnownColor> okColors = names.Except(badColors).ToArray();

    KnownColor randomColorName = okColors[randomGen.Next(okColors.Length)];
    randomColor = Color.FromKnownColor(randomColorName);

    if (!ColorsList.Contains(randomColor) && !randomColor.Name.Contains("Light"))
    {
        ColorsList.Add(randomColor);
    }
    else
    {
        GetRandomColor(randomGen);
    }

    return randomColor;
}

答案 2 :(得分:0)

我认为您的代码不断触及else部分。 请检查您的if()..else()条件

答案 3 :(得分:0)

以下功能适合您。

    List<Color> ColorsList = new List<Color>();
    private Color GetRandomColor(Random randomGen)
            {
                Color randomColor = Color.Red;
                KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));
                KnownColor[] badColors = { KnownColor.AliceBlue };            
                IEnumerable<KnownColor> colors = names.Except(badColors);
                colors = colors.ToArray().Except(ColorsList.Select(x => x.ToKnownColor()));
                KnownColor[] okColors = colors.ToArray();
                KnownColor randomColorName = okColors[randomGen.Next(okColors.Length)];
                randomColor = Color.FromKnownColor(randomColorName);

                if (!ColorsList.Contains(randomColor))
                {
                    ColorsList.Add(randomColor);
                    if (okColors.Count() == 1)
                    {
                        ColorsList.Clear();
                    }
                }
                else
                {
                    GetRandomColor(randomGen);
                }

                return randomColor;
            }

调用此功能

GetRandomColor(new Random())

正如上面提到的那样,问题是由于GetRandomColor函数的无限递归调用。为了解决这个问题,我从okColor列表中删除了已经获取的随机颜色。获得所有颜色后,我已经清除了ColorsList以继续随机化。