创建不更新的 ObservableCollection 的副本
Create a copy of an ObservableCollection that doesn't update
我正在以 xamarin 形式构建一个绑定到对象列表的控件。为了让这个绑定起作用,我需要使用可观察的集合(否则 propertychanged 方法不会触发)。
由于需要使用 OC 而不是列表,我注意到一个非常令人沮丧的交互。每当绑定的 OC 更新时,我的控件中的值会自动更新,即使它们只是 OC 的引用,这是我复制 OC 的方式。
//Internal list of events
private List<EventItem> _events;
void OnEventsChanged(ObservableCollection<EventItem> eventsCollection)
{
//Error handle
List<EventItem> events = eventsCollection.ToList();
//Do something
_events = events;
}
问题出现在 OC 更新时,我想检查 new/deleted 和更改的对象。问题是当 OC 更新时,它也会更新内部列表 (_events
)。这意味着当我去比较旧值和新值时,它们是相同的。
老实说,我真的不明白 c# 如何处理周围对象的复制引用,前段时间我遇到了类似的问题,计算 DateTime.Now
而不是复制已初始化对象的值。
var time = DateTime.Now;
await Task.Delay(1000);
var time2 = time; //This is 1 second later than time, not the value of time (which is what I wanted)
我过去使用过 Objective-C,它具有 MutableCopy
的概念,您可以在其中从现有列表分配新列表,它们具有相同的值但没有链接。
我如何在 C# 中执行此操作,以便我的控件内部列表仅由我而不是 OC 更新?
谢谢
当您编写 _events = events;
时,您创建的不是新的 对象,而是同一对象的引用。 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/index。
您应该克隆(创建对象本身的副本),正如@Matt 在评论中提到的那样。
这很正常。如果我有足够的时间,我会尽力向你解释。
简而言之,observableList(或列表)是对象的引用列表,而不是对象列表。问题是对象没有复制到列表中,但列表包含对不同对象的引用。这意味着如果您执行类似 ToList()
的操作,您将获得另一个对完全相同对象的引用列表。
现在来解决你的问题。只需使用
之类的新对象创建一个新列表
var newList = oldList.Select(x => new Model(x)).ToList();
当然 Model
class 有一个接受 Model
作为参数并复制属性的构造函数。
我正在以 xamarin 形式构建一个绑定到对象列表的控件。为了让这个绑定起作用,我需要使用可观察的集合(否则 propertychanged 方法不会触发)。
由于需要使用 OC 而不是列表,我注意到一个非常令人沮丧的交互。每当绑定的 OC 更新时,我的控件中的值会自动更新,即使它们只是 OC 的引用,这是我复制 OC 的方式。
//Internal list of events
private List<EventItem> _events;
void OnEventsChanged(ObservableCollection<EventItem> eventsCollection)
{
//Error handle
List<EventItem> events = eventsCollection.ToList();
//Do something
_events = events;
}
问题出现在 OC 更新时,我想检查 new/deleted 和更改的对象。问题是当 OC 更新时,它也会更新内部列表 (_events
)。这意味着当我去比较旧值和新值时,它们是相同的。
老实说,我真的不明白 c# 如何处理周围对象的复制引用,前段时间我遇到了类似的问题,计算 DateTime.Now
而不是复制已初始化对象的值。
var time = DateTime.Now;
await Task.Delay(1000);
var time2 = time; //This is 1 second later than time, not the value of time (which is what I wanted)
我过去使用过 Objective-C,它具有 MutableCopy
的概念,您可以在其中从现有列表分配新列表,它们具有相同的值但没有链接。
我如何在 C# 中执行此操作,以便我的控件内部列表仅由我而不是 OC 更新?
谢谢
当您编写 _events = events;
时,您创建的不是新的 对象,而是同一对象的引用。 https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/index。
您应该克隆(创建对象本身的副本),正如@Matt 在评论中提到的那样。
这很正常。如果我有足够的时间,我会尽力向你解释。
简而言之,observableList(或列表)是对象的引用列表,而不是对象列表。问题是对象没有复制到列表中,但列表包含对不同对象的引用。这意味着如果您执行类似 ToList()
的操作,您将获得另一个对完全相同对象的引用列表。
现在来解决你的问题。只需使用
之类的新对象创建一个新列表var newList = oldList.Select(x => new Model(x)).ToList();
当然 Model
class 有一个接受 Model
作为参数并复制属性的构造函数。