C# 如何观察深度嵌套的分层对象?



我正在编写一个 C# mvvm 应用程序,其中我在 UI 层上有一个包含嵌套分层对象的大域模型。大型域模型对象具有许多嵌套对象,这些对象都实现了 INotifyPropertyChanged。现在,假设大模型是一个作业,并且作业在其生命周期内被数据填充,直到它被发送出去。作业在其生存期内纵,并且是活动实体对象,而不是简单的值对象(结构(。

根对象本身也可以通过INotifyPropertyChanged观察到,这会导致两个问题:

观察
  1. 嵌套在第 3 层的对象意味着观察者/侦听器必须通过递归添加事件侦听器直到根目录来跟踪整个大模型 ->可维护性很低,因为每个观察者都需要知道整个大模型直到它的根。对大模型的更改会导致对应用的许多不同部分进行更改。
  2. 一些侦听器
  3. 实际上对对象的不同级别感兴趣,例如,特定侦听器可能希望从级别 2 和级别 4 进行更新。

到目前为止的想法:

  1. 公开一个工厂(模式(,它知道大对象并创建观察者对象:IDisposable,供侦听器被抓取。这样,侦听器只有 ObserverObject 并收到有关值更改的通知,而工厂执行簿记以在将更高级别设置为新值时解决嵌套和失效问题。这样,我只在一个点而不是多个点上解决了内部问题的头痛,并提供了更好的可维护性。
  2. 每个字段和嵌套对象及其字段,以及,...的大模型以 Uri 的形式获得唯一地址。侦听器知道 Uri,并要求存储库接收给定 Uri 的观察者对象。这种方法扩展了第一个选项,因为它允许在不同嵌套级别上拥有相同类型的对象,我偶尔拥有这些对象。

我不太确定哪种方法更好,但我倾向于第二种选择。在我的用例中,我将有不同的侦听器可能对大模型的不同级别感兴趣,此外集合中还有一些动态对象(可以经常添加和删除项目,侦听器需要对此做出反应,例如更新 ViewModel 中的列表(

C# 如何观察深度嵌套的动态对象?

理想情况下,您不应该使用动态类型或在运行时创建的实际类型。禁用编译时类型安全是不好的。但动态可以直接"感染"其他类型的类型。如果在计算的一部分中使用动态,则函数的返回值也会变为动态。但我想你考虑了所有其他选择。

如果必须继续使用动态类型,请考虑使用 ExpandoObject。它似乎直接为这项工作而生。实际上,它只不过是一个带有一些语法糖的Dictionary<string, object>- 最重要的是根据所有"键"/"属性"上的INotifyPropertyChanged更改通知。

我不太明白深度嵌套与此有什么关系。任何集合都需要 3 种类型的更改通知:

  • 在集合项的每个属性(展开对象或某些具体类型(上。
  • 在每次添加和删除元素时。这是可观察集合所负责的
  • 并在暴露列表的属性上。由于 OC 不好批量修改,因此在将其公开给 GUI 并绑定之前,您通常必须在代码隐藏中准备一个新列表。

只要每个人都遵守这些规则,你可以随心所欲地进行下一步。

如果您担心此性能:

  1. 阅读速度咆哮,跳过第 1 部分。
  2. 您正在检索太多数据,用户无论如何都无法处理。我的经验法则是永远不要超过抛出给用户的 100 个字段/值。理想情况下比这少得多。始终在查询中执行尽可能多的筛选、排序等操作。不要检索用户可处理的更多数据。虽然 MVVM 在 GUI 附近有所有这些不错的过滤器和排序选项,但您应该尽量避免使用它们。

最新更新