C# 复杂LINQ请求和奇数整数增量行为

C# 复杂LINQ请求和奇数整数增量行为,c#,linq,C#,Linq,我正在处理一个复杂的LINQ请求 我在助手类(ColorTools)中创建了一个包含8种颜色的列表。我想将这些颜色作为对象实例参数传递 知道我最多创建了5个这样的对象,我创建了一个计数器,每次创建一个这样的对象并在列表中获得相应的颜色时,我都会增加这个计数器 但发生的是我得到了一个OutofRange异常 Dictionary<ItemVM, int> topItem = DisplayedAlarmOccurrences .Select(ao => ao.Item)

我正在处理一个复杂的LINQ请求

我在助手类(ColorTools)中创建了一个包含8种颜色的列表。我想将这些颜色作为对象实例参数传递

知道我最多创建了5个这样的对象,我创建了一个计数器,每次创建一个这样的对象并在列表中获得相应的颜色时,我都会增加这个计数器

但发生的是我得到了一个OutofRange异常

Dictionary<ItemVM, int> topItem = DisplayedAlarmOccurrences
    .Select(ao => ao.Item)
    .GroupBy(t => t)
    .ToDictionary(t => t.Key, t => t.Count())
    .OrderByDescending(t => t.Value)
    .Take(5)
    .ToDictionary(t => t.Key, t => t.Value);

//topItem countains up to 5 elements here
int cpt = 0;

int maxOccItem = topItem.Any() ? topItem.Values.Max() : 10;
SummaryParetoVM summaryItem = new SummaryParetoVM(
    "Items",
    new Axis("Number of Items", 0, maxOccItem),
    topItem.Select(t => new ParetoSerie(
        new []{
            new ParetoInformationPlacement(Place.MIDDLE_CENTER,
                new InformationPlacement()
                {
                    Information = "n° ",
                    Value = t.Key.Index.ToString()
                }),
                new ParetoInformationPlacement(Place.RIGHT_CENTER,
                    new InformationPlacement()
                    {
                        Information = null,
                        Value = t.Value.ToString()
                    }
                )
            }
        )
        {
            //cpt will have a value of 8 here, how is it possible when topItem only got up to 5 items?
            Points = new[]
            {
                new ParetoValuePoint(t.Value,
                    t.Key.Index.ToString(),
                    ColorTools.ChartingBrushes[cpt++])
            }, 
            Title = "Top Items"
        }
    ).Cast<Serie>()
);
作为ParetoValuePoint构造函数的参数

我尝试使用Interlocked.increment增加cpt,但cpt将增加到8,异常以相同的方式出现

注意:这只是一个测试代码,所以代码清洁度与此无关,我只想知道计数器的值是如何超过5的

Edit ChartingBrush是一个公共静态只读列表,在静态类的静态构造函数中启动。代码如下:

public readonly static List<Brush> ChartingBrushes;
static ColorTools() {
    ChartingBrushes = new List<Brush>{
        new SolidColorBrush(Color.FromRgb(115, 115, 115)),
        new SolidColorBrush(Color.FromRgb(241, 90, 96)),
        new SolidColorBrush(Color.FromRgb(122, 195, 106)),
        new SolidColorBrush(Color.FromRgb(90, 155, 212)),
        new SolidColorBrush(Color.FromRgb(250, 167, 91)),
        new SolidColorBrush(Color.FromRgb(158, 103, 171)),
        new SolidColorBrush(Color.FromRgb(206, 112, 88)),
        new SolidColorBrush(Color.FromRgb(215, 127, 180))
    };

    ChartingBrushes.ForEach(b => b.Freeze());
}
公共只读静态列表图表画笔;
静态彩色工具(){
ChartingBrush=新列表{
新的SolidColorBrush(Color.FromRgb(115115115)),
新的SolidColorBrush(颜色来自RGB(241,90,96)),
新的SolidColorBrush(颜色来自RGB(122195106)),
新的SolidColorBrush(颜色来自RGB(90155212)),
新的SolidColorBrush(颜色来自RGB(25016791)),
新的SolidColorBrush(颜色来自RGB(158103171)),
新的SolidColorBrush(颜色来自RGB(206、112、88)),
新的SolidColorBrush(颜色来自RGB(215127180))
};
ForEach(b=>b.Freeze());
}

可枚举项未“关闭”。也就是说,每个枚举都会增加
cpt
。如果要添加
ToList()
,枚举将只运行一次,并将创建一个包含以下结果的列表:

.Cast<Serie>().ToList()
组合ToList和Select with index的示例:

             int[] values = new int[4];
             var list = values.Select((value, index) => index).ToList();

是否使用items初始化了
ColorTools.chartingbrush
?构造函数似乎采用了IEnumerable参数。如果枚举被多次枚举,cpt可能会更大。您可以在强制转换后添加
ToList()
,或者更好地使用带有索引“(值,索引)=>”的选择,而不是variable@Ofiris我编辑了这篇文章来解释画笔是如何绘制的initialized@Me.Name实际上,在.Cast()之后添加.ToList()可以防止发生异常。你能给出一个有详细解释的答案吗?谢谢我的猜测是您枚举集合
topItem。选择…Cast()
至少两次,并且在每次枚举中调用
ParetoSerie
构造函数(10次,2次枚举)。调用
.ToList()
枚举一次集合并将结果存储在列表中。下面的每个枚举都从列表中获取结果,而不是从头计算结果。
    int[] values = new int[4];
    int cntr = 0;

    var enumerable = values.Select(i => cntr++);
    foreach (var i in enumerable)
        Console.WriteLine(i);

    foreach (var i in enumerable)
        Console.WriteLine(i);

    //at this point counter is 8, because the enumeration has run twice. If ToList would be appended to the Select, the result would be 4. 
             int[] values = new int[4];
             var list = values.Select((value, index) => index).ToList();