【问题标题】:Does calling method, and directly reading/setting private fields of the argument, breaks encapsulation?调用方法并直接读取/设置参数的私有字段会破坏封装吗?
【发布时间】:2020-02-13 06:10:20
【问题描述】:

考虑以下代码:

public class Counter
{
    private int _value;

    // public int Value => _value;
    // commented for asking purposes

    public void Increment() {
        _value++;
    }

    public void Decrement() {
        _value--;
    }

    public void CopyOtherCounter(Counter other)
    {
        _value = other._value;
        // the compiler didn't show any error here
        // why it does not break encapsulation?
    }
}

我想问一下这是否意味着打破封装。

编辑:因为我认为我不应该能够读取其他对象私有值,即使它具有相同的类型。因为这可能发生:

public class Person {
    private float _walletMoney; // no getter
    private void StealFrom(Person other) {
        _walletMoney += other._walletMoney; //reading other private wallet
        other._walletMoney = 0; //writing other private wallet
    }
}

void Main() {
    var John = new Person();
    var Bob = new Person();
    John.StealFrom(Bob);
}

【问题讨论】:

  • 为什么你认为它破坏了封装性?
  • 通过创建公共方法和属性,您创建了公共表面积。其他代码可以使用这些公共表面区域与Counter 类进行交互。如果您的公共方法/属性更改任何不会违反封装原则的私有字段。
  • 封装是将一个或多个项目(数据成员和方法)封装在一个物理或逻辑包中,对于 c# 来说,它是一个类。检查这个link

标签: c# class oop


【解决方案1】:

Encapsulation (computer programming)

在面向对象编程 (OOP) 中,封装指的是 将数据与对该数据进行操作的方法捆绑在一起,或者 限制对对象的某些组件的直接访问

根据定义,它仍然是封装的,在类型中,并且有一个非常具体的可访问域!

简单地说,您可以访问定义它的类型中的私有字段,这也包括嵌套的类型/(甚至如果您正在处理对类型的引用),那么(并由规范定义)它是允许的。

要获得这方面的具体文档,您必须深入了解 C# 规范 which you can find here

这里是重要的部分

8.5.2 声明的可访问性

...

  • Private,通过在成员声明中包含 private 修饰符来选择。 private 的直观含义是“访问 限于包含类型

更多

8.5.3 辅助功能域

...

在类型 T 中声明的嵌套成员 M 的可访问域 在程序 P 中,定义如下(注意 M 本身可能 可能是一个类型):

...

  • 如果声明的 M 的可访问性是私有的,则 M 的可访问域是 T 的程序文本。

...

  • 否则,如果 M 是私有的,则如果访问发生在声明 M 的类型内,则允许访问。
  • 否则,类型或成员不可访问,并出现编译时错误。

因此,即使能够在 方法 中访问 私有成员 似乎 违反直觉(当您只能访问reference),它本身仍然是封装的(尽管你可能会反对这个定义),并且可以访问

【讨论】:

  • 啊,我明白了,请加粗这个:您可以访问定义它的类型内的私有字段。
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 2013-05-14
  • 2021-09-28
  • 2012-11-28
  • 2018-05-09
  • 1970-01-01
相关资源
最近更新 更多