c# - 在 foreach 循环中将项目添加到 ObservableCollection 会影响上级列表中的整个项目?
问题描述
我会尽量简短。
我有一个名为Error
. 此类包含一个名为的属性Suggestions
,它是一个ObservableCollection<string>
.
在一种方法中,我创建了一个用 LINQ 语句Error
命名的 s列表,AllInstances
然后foreach
在该列表上执行循环。在循环内部,我将一项添加到对象的Suggestions
集合中Error
。
问题在于,在循环的每一轮中,该项目都会添加到AllInstances
. 因此,如果循环有 3 个回合,那么每个成员AllInstances
都会添加 3 个项目!
正常行为应该是每个Suggestions
集合都添加了 1 个项目,而不是 3 个。
这是代码:
错误类
public class Error : INotifyPropertyChanged, ICloneable
{
public ObservableCollection<string> Suggestions { get; set; }
}
方法的代码
List<Error> AllInstances = (from paragraph in DocRef.LatestState
from error in paragraph.Errors
where error.Word == sourceError.Word
select error).ToList();
foreach (Error _er in AllInstances)
{
_er.Suggestions.Add(newSuggestion);
}
// At this point, if "AllInstances.Count" was 3, every "_er.Suggestions" in "AllInstances"
// will also have 3 items in it!
这对我来说似乎很不合逻辑,以至于我高度怀疑这是我已经做过的事情,或者是我还不知道的类型结构的基本知识。
我很感激任何帮助。谢谢你。
解决方案
好的,正如我在上一次对该问题的评论中提到的那样,我研究了Error
在一些需要它的情况下克隆类的方式。原来我在方法中克隆了这样的对象:
public object Clone ()
{
return new Error
{
...
Suggestions = Suggestions,
...
};
}
我注意到Error
class 的所有其他属性都是默认类型(不可变?),例如string
, int
and bool
,唯一不同的是 Suggestions 类型的集合ObservableCollection<string>
。我想可能是因为其他属性都表现正确并且没有导致引用同一实例的问题,这个集合在设计上与其他集合不同,需要手动重新实例化。所以我做了:
public object Clone ()
{
return new Error
{
...
Suggestions = new ObservableCollection<string>(Suggestions),
...
};
}
我只是在方法中重新创建了属性,Clone
解决了在 foreach 循环中引用同一实例的问题。
我希望对代码有更深入了解的人可以启发我和其他可能偶然发现这个问题的人,关于这个问题的逻辑以及那些不可变类型和ObservableCollection
.
推荐阅读
- python - 我想在 django 中将 pdf 与 httpresponse 合并
- javascript - 如何在不提及 javascript 中的名称的情况下访问对象内部命名对象内部的重复元素数据?
- python - 遍历一个元组以形成一个字符串
- revit-api - 无法更新地形材质
- python-3.x - 遍历 SRT 文件直到找到索引
- android - Android Kotlin:如何使用哈希密码登录
- python - 使用 BS4 和请求使用代理解析 RSS 提要时出错
- python - PyAutogui:出现图像时如何停止循环?
- android - 我怎样才能启动android项目。(安装应用命令失败:gradlew.bat app:installDebug)
- xml - 如何使用 XML 使浮动标签适用于 Android 设备的不同屏幕尺寸?