如何在保持封装的同时访问位于不同 class 中的对象? (数据?)

How to get access to an object which is in a different class while maintaining encapsulation? (data?)

我正在用 c# 制作一个 Phone 图书控制台应用程序,这是我迄今为止最大的项目:) 我认为自己是初学者,但我很想提高

我正在使用 3 个 classes 来创建这个,它们是:

修改class负责联系人的增删改查。搜索和显示 classes 是不言自明的。我也有每个 classes.

的接口

问题:

我在修改 class 中创建了一个 KeyValuePair 列表,如下所示:

private List<KeyValuePair<string , int>> AllContacts { get; set; } 

public Modifications()
{ 
   AllContacts = new List<KeyValuePair<string, int>>(); 
}

我想在我的其他 classes 中访问这个 AllContacts 对象。但是我没能在保持封装的同时实现这一点。 AllContacts 就像我的主要数据来源。我在此列表中添加联系人。我不希望我的主要方法中的某个人像 modificationObject.AllContacts.Clear();


我的尝试:

[如果你愿意可以跳过这个:)]

我的悲伤尝试第 1 部分:

- 从基础 class 继承显示 Class 修改

-在我的修改 class 中,我创建了一个 List<KeyValuePair<string , int>> 类型的受保护 属性 并将其命名为 'AllContacts' 作为数据库

-在我的 Display class 中,我创建了一个与上面相同类型的私有 属性 并将其命名为 _allContacts

-在我的 Display class 的构造函数中,我请求了一个名为 modObject

的修改类型对象

-我说过,_data = modObject.AllContacts;

-没用,我想是因为只有派生对象才能得到这个属性?

我的悲伤尝试第二部分:

-假设我的假设是正确的,我尝试将 modObject 向下转型为它派生的 class 类型 Display。而是出现编译错误。试图创建一个受保护的 GetAllContacts() 方法,编译错误。

我的悲伤尝试第六部分:

-最后,我只是把它变成了一个 public 属性 和一个 private setter。我的应用程序有效,但人们仍然可以以某种方式在我的主要方法中使用 x.AllContacts.Clear()


问题:

谢谢:)


如果需要附加上下文:(当前正在运行的应用程序,无方法)

修改class:

 public class Modifications
    {
        public List<KeyValuePair<string, int>> AllContacts { get; private set; }
        public Modifications()
        {
            AllContacts = new List<KeyValuePair<string, int>>();
        }
....

显示class:

public class Display : IDisplayable
{
    private List<KeyValuePair<string, int>> AllContacts;
    public Display(Modifications modificationsObject)
    {
        AllContacts = modificationsObject.AllContacts;
    }

....


除非您想禁止所有其他方法使用 setter,否则您不需要为私有变量成员声明访问器,但使用只读字段的速度比 属性 更快避免无用的 CPU Proc 调用,它们会白白消耗滴答计时。

要从其他 classes 访问它,您必须像这样将其声明为 public:

public List<KeyValuePair<string , int>> AllContacts { get; private set; } 

因此其他 classes 可以读取引用并调用 List 实例的变量访问器和方法,如 Count 和 Add,但他们不能替换此实例引用,从而更改对象本身。

但是如果你想禁止操作列表,你可以实现所有你想公开的包装方法,如计数、添加、删除、删除等以及索引器,你可以指出 class 实现 IExumerable<KeyValuePair<string , int>>.

通过这种方式你可以有一个强大的封装:

public class MyClass: IEnumerable<KeyValuePair<string , int>>
{
  private readonly List<KeyValuePair<string , int>> AllContacts
    = new List<KeyValuePair<string , int>>();

  public int ContactsCount
  {
    get { return AllContacts.Count; }
  }

  public KeyValuePair<string , int> this[int index]
  {
    get { return AllContacts[index]; }
    set { AllContacts[index] = value; }  // don't declare if readonly
  }

  // if adding is allowed
  public int Add(KeyValuePair<string , int> item)
  {
    ...
  }

  ...

}