C# 解决替换foreach循环中的项的问题

C# 解决替换foreach循环中的项的问题,c#,key-value,C#,Key Value,在下面的示例代码中,我想用新项替换字典中的项,或者为该项分配新值我该怎么做? 这是我的代码: dynamic data = jss.Deserialize<dynamic>(jsonText); foreach (KeyValuePair<string,object> item in data["typeData"]) { if(item.Key == "somevalue") { item = new KeyValueP

在下面的示例代码中,我想用新项替换字典中的项,或者为该项分配新值我该怎么做?

这是我的代码:

dynamic data = jss.Deserialize<dynamic>(jsonText);

foreach (KeyValuePair<string,object> item in data["typeData"])
{
    if(item.Key == "somevalue")
        {
            item = new KeyValuePair<string,object>();
        }                               
}
dynamic data=jss.Deserialize(jsonText);
foreach(数据[“typeData”]中的KeyValuePair项)
{
如果(item.Key==“somevalue”)
{
item=新的KeyValuePair();
}                               
}
我得到:

无法分配给“项”,因为它是“foreach迭代变量”


必须有解决办法。

foreach
被视为只读上下文

不要像消息所说的那样使用
foreach
,将循环转换为常规
for
循环

从MSDN:

This error occurs when an assignment to variable occurs in a read-
only context. Read-only contexts include foreach iteration variables,
using variables, and fixed variables. To resolve this error, avoid
assignments to a statement variable in using blocks, foreach
statements, and fixed statements.

在您的情况下,对象
不是一个引用,它只是一个副本,因此您对它所做的任何更改都不会导致原始对象的更改。

取决于您想要什么。是否只需要覆盖该值?我这样认为是因为替换键和值将是一个非常不同的操作(删除一项,插入另一项)

只需迭代键而不是集合(假设它是字典):


代码的问题在于,您试图更改用作占位符的变量的值。变量“item”只是与字典中存在的引用相同;更改“item”引用的对象实际上不会更改字典本身中的任何内容,更重要的是,它会破坏字典中循环的逻辑

除了无法重新分配占位符外,还不允许在使用该字典的foreach循环中添加或删除字典中的项目,因为这也会打乱遍历字典项目(即“当前”项目)的逻辑幕后枚举器的项现在不再存在,因此枚举器可能会失去其在集合中的位置而无法继续

解决方法是在更改原始集合时枚举不同的集合。基本上,这样的任务需要两个过程:首先收集要更改的项,然后枚举该集合并对原始集合进行更改:

...

var itemsToChange = new List<KeyValuePair<string, object>>();

foreach (var item in data["typeData"])
{
    if(item.Key == "somevalue")
       itemsToChange.Add(item);                                       
}

foreach(var item in itemsToChange)
{
    //even here you can't just "swap out" KVPs;
    //you must remove the old and add the new
    data["typeData"].Remove(item);
    data["typeData"].Add(someNewString, someNewObject);
}
。。。
var itemsToChange=新列表();
foreach(数据[“typeData”]中的变量项)
{
如果(item.Key==“somevalue”)
itemsToChange.Add(项目);
}
foreach(itemsToChange中的var项目)
{
//即使在这里,您也不能仅仅“交换”KVP;
//您必须删除旧的并添加新的
数据[“类型数据”]。删除(项目);
数据[“typeData”]。添加(someNewString,someNewObject);
}

也许您的问题中缺少了一些东西,但解决方法似乎是完全避免循环:

dynamic data = jss.Deserialize<dynamic>(jsonText); 
var item = new KeyValuePair<string, object>("somevalue", data["somevalue"]);
dynamic data=jss.Deserialize(jsonText);
var项=新的KeyValuePair(“somevalue”,数据[“somevalue”);
或许:

dynamic data = jss.Deserialize<dynamic>(jsonText);
DoSomethingWith(data["somevalue"]);
dynamic data=jss.Deserialize(jsonText);
DoSomethingWith(数据[“somevalue”]);

循环的原因是什么?

您必须使用for循环,或者存储要更改的变量,并在foreach循环之外进行更改。

听起来很简单,但我认为动态数据类型没有该循环的.count或.length。请举个例子。@capdragon-使用foreach循环原始列表并存储引用e到原始列表中需要更改的内容(转换为新列表),然后对新列表使用foreach更新原始列表。但是,正如您的评论中提到的
Karl Knechtel
,怎么可能有多个项目具有相同的键?@capdragon-“数据”是动态的。它似乎是某种包,其中一个项目键入了“typeData”是一个字典。需要将该项显式转换为字典类型,以便foreach知道它使用的是什么,但它只与如何更改该字典元素的问题有最小的关联。“somevalue”实际上是一个调用获取值的函数..不重要。你真正想做什么?为什么你会有一个空的
KeyValuePair
?怎么可能有多个项具有键
“somevalue”
(即,你为什么需要循环)?非常好的一点Karl(你为什么需要循环).这是关键。嗯,这是你的代码和你的编码问题,所以你告诉我!:)为什么这是否定的?这只是一种可以+1工作的方法。我当然不需要DV,但可能是因为您不需要两次传递,但可以在一次传递中完成(OP要求进行替换,因此不需要添加/删除)。如果他只需要将值替换为键“somevalue”:
data[“somevalue”]=@phoog是的,但由于他在循环,我想“someValue”就是一个例子,而且有几个值是可能的,我也想到了。但后来我认为这几个值必须来自某个地方,我想不出它们可能来自哪个地方,这样的循环才是最好的解决方案。
dynamic data = jss.Deserialize<dynamic>(jsonText); 
var item = new KeyValuePair<string, object>("somevalue", data["somevalue"]);
dynamic data = jss.Deserialize<dynamic>(jsonText);
DoSomethingWith(data["somevalue"]);