我正在建立绑定到对象列表的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更新?
谢谢
答案 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注释中提到的对象(创建对象本身的副本)。