创建一个不会更新的ObservableCollection的副本

时间:2018-10-24 15:15:38

标签: c# xamarin xamarin.forms observablecollection

我正在建立绑定到对象列表的xamarin形式的控件。为了使这种绑定起作用,我需要使用可观察的集合(否则,不会更改属性更改的方法。)

我注意到,由于需要使用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更新时,我想检查新对象/已删除对象和更改过的对象。问题是,当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更新?

谢谢

2 个答案:

答案 0 :(得分:4)

那是完全正常的。如果我有足够的时间,我会尽力向您解释。

简而言之,observableList(或List)是对对象的引用列表,而不是对象列表。问题是对象没有复制到列表中,而是列表包含对不同对象的引用。这意味着,如果您执行类似ToList()的操作,则会得到另一个引用,它们指向完全相同的对象。

现在解决您的问题。只需使用类似

的新对象创建一个新列表
var newList = oldList.Select(x => new Model(x)).ToList();

当然,Model类具有一个构造函数,该构造函数接受Model作为参数并复制属性。

答案 1 :(得分:2)

编写_events = events;时,您创建的不是新的对象,而是同一对象的引用https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/index。 您应该克隆@Matt注释中提到的对象(创建对象本身的副本)。