简体   繁体   English

无法评估表达式C#

[英]Cannot evaluate expression c#

I'm getting the below error at var okColors = colors.ToArray(); 我在var okColors = colors.ToArray();遇到以下错误var okColors = colors.ToArray();

Cannot evaluate expression because the current thread is in a stack overflow state. 由于当前线程处于堆栈溢出状态,因此无法求值表达式。

Can you please help on this? 你能帮忙吗?

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

Your code throws StackOverflowException and when it happens debugger can no longer evaluate any variables resulting in error you see. 您的代码将引发StackOverflowException,并且调试器无法再评估会导致错误的任何变量。

Why code have StackOverflowException : 为什么代码具有StackOverflowException

  • code uses wrong way to generate random number and ends up with the same number for enough calls. 代码使用错误的方式生成随机数,并以相同的数目结束足以进行的调用。 Correct way - How do I generate a random int number in C#? 正确方法- 如何在C#中生成随机整数? - use static Random instance. -使用静态Random实例。
  • as result checks for .Contains constantly fail and code essentially becomes infinite recursion: 结果检查.Contains总是失败,并且代码本质上变成了无限递归:

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

Additional reading: How do I prevent and/or handle a StackOverflowException? 其他阅读: 如何防止和/或处理StackOverflowException?

You have to use the same instance of Random for each recursive call, do not create a new one in each function call. 您必须为每个递归调用使用相同的Random实例 ,而不是在每个函数调用中创建一个新的实例 If a new Random instance is created in the function every time it's called, you might keep getting the same values and not random values as you might expect. 如果在每次调用该函数时都创建了一个新的Random实例,则可能会不断获得相同的值,而不是您期望的随机值。

Here is another thread you might want to look at: 这是您可能要查看的另一个线程

randomNumber creates a new instance of Random each time... which in turn creates a new pseudo-random number generator based on the current time... which doesn't change as often as you might think. randomNumber每次都会创建一个Random的新实例...这又会根据当前时间创建一个新的伪随机数生成器...它的变化频率没有您想像的那么大。

In the linked thread, Jon Skeet also suggested against using a static Random variable. 在链接的线程中,Jon Skeet还建议不要使用静态的Random变量。

Use the same instance of Random repeatedly... but don't "fix" it by creating a static Random variable. 重复使用相同的Random实例...但是不要通过创建静态Random变量来“修复”它。 That won't work well either in the long term, as Random isn't thread-safe. 从长远来看,这也不行,因为Random不是线程安全的。

One option can be to pass an instance of Random as parameter to the function, this would ensure that the same Random instance is being passed along the recursive chain: 一种选择是将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;
}

I think your code continuously hitting the else part. 我认为您的代码不断触及else部分。 Please check your if()..else() condition 请检查您的if()..else()条件

The following function will work for you. 以下功能将为您服务。

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

To call this function 调用此功能

GetRandomColor(new Random())

As many stated above the issue was due to infinite recursion call of GetRandomColor function. 如上文所述,该问题是由于GetRandomColor函数的无限递归调用所致。 To fix it, I have removed already fetched random colors from okColor list. 为了解决这个问题,我从okColor列表中删除了已经获取的随机颜色。 Also after getting all colors, i have cleared the ColorsList to continue the randomization. 同样在获得所有颜色之后,我也清除了ColorsList以继续随机化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM