c# – 在不违反类型安全的情况下将不透明对象返回给调用者

前端之家收集整理的这篇文章主要介绍了c# – 在不违反类型安全的情况下将不透明对象返回给调用者前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个方法应该返回当前状态的快照,另一个方法是恢复该状态.
  1. public class MachineModel
  2. {
  3. public Snapshot CurrentSnapshot { get; }
  4. public void RestoreSnapshot (Snapshot saved) { /* etc */ };
  5. }

状态Snapshot类对调用者应该是完全不透明的 – 没有可见的方法属性 – 但是它的属性必须在MachineModel类中可见.我显然可以通过向下转换来实现这一点,即让CurrentSnapshot返回一个对象,并让RestoreSnapshot接受一个对象参数,它将其转换回快照.

但这样的强迫铸造让我觉得很脏.什么是最好的替代设计,允许我既是类型安全的又是不透明的?

更新解决方案:

我结束了接受的答案和关于接口的建议. Snapshot类是一个公共抽象类,在MachineModel中有一个私有实现:

  1. public class MachineModel
  2. {
  3. public abstract class Snapshot
  4. {
  5. protected internal Snapshot() {}
  6. abstract internal void Restore(MachineModel model);
  7. }
  8.  
  9. private class SnapshotImpl : Snapshot
  10. {
  11. /* etc */
  12. }
  13.  
  14. public void Restore(Snapshot state)
  15. {
  16. state.Restore(this);
  17. }
  18. }

由于Snapshot的构造函数方法是内部的,因此程序集外部的调用者将其视为完全不透明且无法从中继承.程序集中的调用者可以调用Snapshot.Restore而不是MachineModel.Restore,但这不是一个大问题.此外,在实践中,您永远无法实现Snapshot.Restore而无法访问MachineModel的私有成员,这应该阻止人们尝试这样做.

解决方法

您可以反转依赖关系并使Snapshot成为MachineModel的子(嵌套类).然后,Snapshot只有一个公共(或内部)Restore()方法,该方法将MachineModel的实例作为参数.由于Snapshot被定义为MachineModel的子级,因此可以看到MachineModel的私有字段.

要恢复状态,下面的示例中有两个选项.您可以调用Snapshot.RestoreState(MachineModel)或MachineModel.Restore(Snapshot)*.

  1. public class MachineModel
  2. {
  3. public class Snapshot
  4. {
  5. int _mmPrivateField;
  6.  
  7. public Snapshot(MachineModel mm)
  8. {
  9. // get mm's state
  10. _mmPrivateField = mm._privateField;
  11. }
  12.  
  13. public void RestoreState(MachineModel mm)
  14. {
  15. // restore mm's state
  16. mm._privateField = _mmPrivateField;
  17. }
  18. }
  19.  
  20. int _privateField;
  21.  
  22. public Snapshot CurrentSnapshot
  23. {
  24. get { return new Snapshot(this); }
  25. }
  26.  
  27. public void RestoreState(Snapshot ss)
  28. {
  29. ss.Restore(this);
  30. }
  31. }

例:

  1. MachineModel mm1 = new MachineModel();
  2. MachineModel.Snapshot ss = mm1.CurrentSnapshot;
  3. MachineModel mm2 = new MachineModel();
  4. mm2.RestoreState(ss);

*将Snapshot.RestoreState()作为内部并将所有调用者放在程序集之外是最简洁的,因此执行还原的唯一方法是通过MachineModel.RestoreState().但是你在Jon的回答中提到在同一个程序集中会有调用者,所以没有多大意义.

猜你在找的C#相关文章