- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
由于 SortedDictionary.ValueCollection
的 Enumerator
行为与其他枚举器不同,我们最近遇到了一个错误。我已经设法将问题缩小到以下(无意义的)示例:
public void Example()
{
var sorted = new SortedDictionary<string, int>
{
{"1", 1 },
{"3", 3 },
{"0", 0 },
{"2", 2 },
{"4", 4 }
};
var fromValues = sorted.Values.GetEnumerator();
fromValues.MoveNext();
var fromLinq = sorted.Select(x => x.Value).GetEnumerator();
fromLinq.MoveNext();
var fromDictionary = new Dictionary<string, int>(sorted).Values.GetEnumerator();
fromDictionary.MoveNext();
for (var i = 0; i < 3; i++)
{
Console.WriteLine($"Printing for {i}");
Print(" From Values: ", fromValues, i);
Console.WriteLine(" ------------");
Print(" From Linq: ", fromLinq, i);
Console.WriteLine(" ------------");
Print(" From Dictionary: ", fromDictionary, i);
Console.WriteLine();
}
}
private void Print(string prefix, IEnumerator<int> enumerator, int value)
{
do
{
Console.WriteLine(prefix + "Value in loop: " + enumerator.Current);
if (enumerator.Current == value)
{
Console.WriteLine(prefix + "Selected Value: " + enumerator.Current);
break;
}
} while (enumerator.MoveNext());
}
这将产生以下输出:
Printing for 0
From Values: Value in loop: 0
From Values: Selected Value: 0
------------
From Linq: Value in loop: 0
From Linq: Selected Value: 0
------------
From Dictionary: Value in loop: 0
From Dictionary: Selected Value: 0
Printing for 1
From Values: Value in loop: 0
From Values: Value in loop: 1
From Values: Selected Value: 1
------------
From Linq: Value in loop: 0
From Linq: Value in loop: 1
From Linq: Selected Value: 1
------------
From Dictionary: Value in loop: 0
From Dictionary: Value in loop: 1
From Dictionary: Selected Value: 1
Printing for 2
From Values: Value in loop: 0
From Values: Value in loop: 2
From Values: Selected Value: 2
------------
From Linq: Value in loop: 1
From Linq: Value in loop: 2
From Linq: Selected Value: 2
------------
From Dictionary: Value in loop: 0
From Dictionary: Value in loop: 1
From Dictionary: Value in loop: 2
From Dictionary: Selected Value: 2
如您所见,三个 Iterators
的行为不同:
Current
在传递给函数时始终为 0,但 MoveNext
在循环中推送到正确的值。Iterator
的预期。Enumerator
传递给函数时重置。我怀疑 SortedDictionary.ValueCollection.Enumerator
是一个结构并且由 linq 生成的是一个引用类型这一事实与它有关。但这并不能解释为什么它不像 Dictionary 中的 Enumerator
那样工作。
最佳答案
我相信答案是 SortedDictionary
值枚举器是一个结构(类型为 System.Collections.Generic.SortedDictionary<string,int>.ValueCollection.Enumerator
)。
发生的事情是,每次将结构传递给 Print()
时都会复制该结构。方法,因此该方法始终使用原始枚举器的副本 - 这会导致工作异常。
下面的程序演示了这一点:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
Example();
}
public static void Example()
{
var sorted = new SortedDictionary<string, int>
{
{"1", 1 },
{"3", 3 },
{"0", 0 },
{"2", 2 },
{"4", 4 }
};
var fromValues1 = sorted.Values.GetEnumerator();
// fromValue1 type is struct System.Collections.Generic.SortedDictionary<string,int>.ValueCollection.Enumerator
fromValues1.MoveNext();
while (printNextValue(fromValues1)) // Prints 0 once for each value in the dictionary.
;
Console.WriteLine("-----------------");
IEnumerator<int> fromValues2 = sorted.Values.GetEnumerator();
// fromValues2 type is boxed struct System.Collections.Generic.SortedDictionary<string,int>.ValueCollection.Enumerator
fromValues2.MoveNext();
while (printNextValue(fromValues2)) // Prints each value in the dictionary.
;
}
static bool printNextValue(IEnumerator<int> enumerator)
{
Console.WriteLine(enumerator.Current);
return enumerator.MoveNext();
}
}
第一个循环输出全零,而第二个循环输出正确的值。
此示例中两个循环之间的唯一区别是第一个迭代器声明为:
var fromValues1 = sorted.Values.GetEnumerator();
第二个声明为:
IEnumerator<int> fromValues2 = sorted.Values.GetEnumerator();
.
第一个声明将导致 fromValues1
是一个结构,而第二个是一个盒装结构。
因为结构是装箱的,这意味着它在传递给 printNextValue()
时不会被复制,这意味着 printNextValue()
将使用原始枚举器而不是它的副本。
但是,这并不能解释循环终止的原因!如果每次都复制原始枚举器位置 printNextValue()
被调用,那么循环永远不会终止,因为原始枚举器的位置永远不会更新。
这让我相信 SortedDictionary.Enumerator
的实现有些复杂意味着当复制结构时,它的一些数据会被复制,但有些不会。
(查看源代码,我怀疑这是由于枚举器实现的 Current
是一个被复制的值类型,但是 MoveNext()
似乎操纵一个堆栈 - 作为一个引用类型 - 在两者之间共享枚举器的所有副本。但是,代码有点太复杂了,我目前有限的时间无法分析...)
关于c# - SortedDictionary.ValueCollection 的枚举器行为不同于其他枚举器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60005524/
在 C# 中,如何使用 LINQ 过滤 SortedDictionary,生成一个子集,该子集也是 SortedDictionary?例如。我想写 SortedDictionary source =
我有一个要求,我已经有一个现有的 SortedDictionary .现在我正在创建一个不同的 SortedDictionary并喜欢在第一个中添加它。怎么做? 最佳答案 只需将它传递给构造函数: v
我有 2 个 SortedDictionary“mainsd”&&“valuesd”。我正在尝试编程的条件如下: If the sum of Values of the 2 Keys above th
只是想知道:如果我有两个 SortedDictionary 对象,找出它们的内容是否相同的最快方法是什么?循环所有键并检查值听起来不像是最佳解决方案。仅检查 GetHashCode() 就足够了吗?
我有一个对象列表。这些对象有很多属性,包括价格和数量。我需要创建一个包含键“价格”和值“数量”的新字典。如果两个对象具有相同的价格,则生成的字典应将价格作为键,将两个对象的数量之和作为值。据我所知,我
我有一个对象列表。这些对象有很多属性,包括价格和数量。我需要创建一个包含键“价格”和值“数量”的新字典。如果两个对象具有相同的价格,则生成的字典应将价格作为键,将两个对象的数量之和作为值。据我所知,我
我正在使用一个 SortedDictionary,其中键是整数,值是字符串。 SortedDictionary dic = new SortedDictionary(); 现在假设我添加如下值 dic
我从来没有使用过 SortedDictionary,我只是好奇,当你向它添加值时,例如,在 for 循环中,是在添加值时自动对它们进行排序,还是在添加它们之后必须对它们进行排序. 最佳答案 这是自动完
所以基本上我有这样的事情: private SortedDictionary> example = new SortedDictionary>(new PriorityComparer()); pub
我在 Internet 上看到了很多关于此的引述,但没有官方文档?谁能告诉我在哪里可以获得这方面的信息? 最佳答案 这不应该记录在案,因为它是一个实现细节。 例如,SortedDictionary 的
我读了here与 SortedList 不同,SortedDictionary 不允许索引检索。那么如何在下面的代码片段中正确获取nameAddr["C"]呢? SortedDicti
这个问题在这里已经有了答案: Reverse Sorted Dictionary in .NET (5 个答案) 关闭 8 年前。 我有以下字典: SortedDictionary dictiona
我创建了一个使用 SortedDictionary 来存储和操作数据的类。该类在多线程环境中实现时效果很好。现在,我想通过为内部 SortedDictionary 类编写一个包装类来使类线程安全。我想
我必须尽快从 SortedDictionary 中删除第二个元素。字典 ( SortedDictionary> ) 最多可以包含 20'000 个元素。所以我想出了这个解决方案: try {
由于 SortedDictionary.ValueCollection 的 Enumerator 行为与其他枚举器不同,我们最近遇到了一个错误。我已经设法将问题缩小到以下(无意义的)示例: publi
我正在研究我的一个项目的代码优化,我想知道如何为 SortedDictionary 设置初始容量。我知道我可以在构造函数中很容易地对列表和字典执行此操作。但是我该如何对 SortedDictionar
有很多很多线程讨论如何从字典获取“第一个”项目,并且有各种各样的答案来解释为什么这样的事情实际上并不是一件好事这个想法是因为没有内部排序。但我的是一个 SortedDictionary,所以这些参数不
例如,假设我有大量关于数据库中大量日期的一组餐厅的数据,我需要分析/输出给用户。 因此,在我的代码中,我有一个自定义类,用于保存每个日期每个餐厅的数据 - 例如: Public Class DateD
C# 中 SortedDictionary.Count 的成本是多少?它是检索一些整数,还是遍历树? 最佳答案 它只是从一个字段返回一个值,因此成本应该可以忽略不计。 关于c# - SortedDic
我有一个 SortedDictionary 的集合: SortedDictionary _variableValues = new SortedDictionary(); 键值对如下所示: ThkPo
我是一名优秀的程序员,十分优秀!