希望在C#中修改字典的简单问题

时间:2008-11-29 07:00:08

标签: c# .net dictionary

我在一个名为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。但是,您可以看到代码应该可以正常工作 - 因为我没有添加或删除任何值,只是修改了值。但是,我理解为什么它害怕我尝试这个。

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

我真的不想创建整个数组的副本,因为它是很多数据并且会像我的感恩节一样吃掉我的ram。

谢谢,   戴夫

3 个答案:

答案 0 :(得分:2)

是否有任何理由不能同时使用键和值填充字典?

foreach(var key in someListOfKeys)
{
    questions.Add(key, retrieveGuess(key.userID, key.movieID);
}

答案 1 :(得分: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代码。
  • 您未在致电Dispose的{​​{1}}上致电IEnumerator<T>。如果您只使用GetEnumerator,您的代码将更简单并且更安全。
  • foreach几乎肯定是一个班级。你有把它变成结构的真正理由吗?

答案 2 :(得分:0)

将字典键存储在临时集合中,然后遍历临时集合并使用键值作为索引器参数。这应该可以解决这个问题。