我在第三方库中有一个属性是List<T>
,并且我希望在列表更改时得到通知。有没有办法在不修改第三方库代码的情况下实现这一点?
public sealed class ThirdPartyObject
{
public List<string> Names { get; } = new List<string>();
}
换句话说,我需要一种机制,允许我的客户端代码在List<T>
更改时得到通知,以便我可以采取适当的行动。
我试过这样做,但它没有工作:
var col = new ObservableCollection<string>(myObj.Names);
col.CollectionChanged += (sender, args) =>
{
// notify
};
如果库没有任何事件或回调,则无法立即获得通知。
您也许可以通过对库进行拆解和重新编译来修改它。但这可能会违反与库作者之间的许可协议(如果有的话)。在运行时也可以这样做,但我建议不要使用这两种方法,因为如果发布了新版本的库,它可能会中断。
一个解决方法是使用轮询。创建您选择的计时器,定期比较当前列表与保存的副本(在执行此操作时要记住线程安全),为任何不同的项引发事件,并创建列表的新副本。使用轮询器意味着在事件发生时不会引发事件,并且即使没有进行任何更改,它也会使用一些资源来比较列表。另一方面,如果发生频繁的更改,最好是引发一些不频繁的事件,而不是针对每个更改。
如果你不关心重复或排序,你可以使用hashSet来比较两个列表:
var newItems = newList.ToHashSet();
var removedItems = oldList.ToHashSet();
var intersection = newItems.ToHashSet();
intersection.IntersectWith(removedItems);
removedItems.ExceptWith(intersection);
newItems.ExceptWith(intersection);