0

我在一个名为 current 的变量中有一个巨大的空白值字典,如下所示:

struct movieuser {blah blah blah}
Dictionary<movieuser, float> questions = new Dictionary<movieuser, float>();

所以我正在遍历这本字典,需要填写“答案”,如下所示:

for(var k = questions.Keys.GetEnumerator();k.MoveNext(); )
{
    questions[k.Current] = retrieveGuess(k.Current.userID, k.Current.movieID);
}

现在,这不起作用,因为我尝试修改正在循环的字典时得到了 InvalidOperationException。但是,您可以看到代码应该可以正常工作 - 因为我没有添加或删除任何值,只是修改了值。但是,我理解为什么它害怕我尝试这样做。

这样做的首选方法是什么?在不使用迭代器的情况下,我想不出一种方法来遍历字典。

我真的不想创建整个数组的副本,因为它包含大量数据并且会像感恩节一样吃掉我的内存。

谢谢,戴夫

4

3 回答 3

2

有什么理由不能同时用键和值填充字典吗?

foreach(var key in someListOfKeys)
{
    questions.Add(key, retrieveGuess(key.userID, key.movieID);
}
于 2008-11-29T07:04:49.090 回答
2

马特的回答,首先获得钥匙,分开是正确的方法。是的,会有一些冗余——但它会起作用。我会采用一个易于调试和维护的工作程序,而不是一个无法工作或任何一天都难以维护的高效程序。

不要忘记,如果你创建MovieUser一个引用类型,那么数组的大小只会与你拥有的用户数量一样多——这非常小。一百万用户在 x64 上只会占用 4MB 或 8MB。你真的有多少用户?

因此,您的代码应类似于:

IEnumerable<MovieUser> users = RetrieveUsers();

IDictionary<MovieUser, float> questions = new Dictionary<MovieUser, float>();
foreach (MovieUser user in users)
{
    questions[user] = RetrieveGuess(user);
}

如果您使用的是 .NET 3.5(因此可以使用 LINQ),那就更简单了:

IDictionary<MovieUser, float> questions = 
    RetrieveUsers.ToDictionary(user => user, user => RetrieveGuess(user));

请注意,如果RetrieveUsers()可以从其源(例如文件)流式传输用户列表,那么无论如何它将是有效的,因为您在填充字典时一次不需要知道多个用户。

对其余代码的一些评论:

  • 代码约定很重要。将类型和方法的名称大写以适应其他 .NET 代码。
  • 你不是在调用DisposeIEnumerator<T>调用产生的GetEnumerator. 如果你只使用foreach你的代码会更简单更安全。
  • MovieUser几乎可以肯定是一个类。你真的有充分的理由让它成为一个结构吗?
于 2008-11-29T07:36:08.793 回答
0

将字典键存储在临时集合中,然后遍历临时集合并将键值用作索引器参数。这应该让你绕过异常。

于 2008-11-29T07:06:10.723 回答