gpt4 book ai didi

c# - 一种非常常见的 C# 模式,它打破了非常基本的 OOP 原则

转载 作者:可可西里 更新时间:2023-11-01 07:51:03 27 4
gpt4 key购买 nike

这是一个非常简单的问题,我仍然很不安:

为什么现在广泛接受类通过访问器方法返回对其私有(private)成员的引用?这不是完全破坏了封装原则吗?如果这没问题,那为什么不公开该成员呢!?

public class EncapsulationViolator
{
private object abuseMe;

public object AbuseMe
{
get { return abuseMe; }
}
}

编辑 我考虑的情况是这样的

EncapsulationViolator ev = new EncapsulationViolator();

object o = ev.AbuseMe;

o.SetValue(newValue);

现在 ev 的状态通过传递性发生了变化,因为它的成员 abuseMe 的状态发生了变化。

在 DDD 的上下文中,如果对象是聚合根,则这是不可行的。我引用

Allow external objects to hold references to the root only. Transient references to internal members can be passed out for use within a single operation only. Because the root controls access, it cannot be blindsided by changes to the internals.

[Domain-Driven Design, Eric Evans]

... setters schmetters ...

最佳答案

您将 C++ 术语“引用”与 C# 传递对象按值(它们的引用)这一事实混为一谈。

在这种情况下,getter AbuseMe 的调用者不能换出私有(private)字段abuseMe。因此,不存在违反封装的问题。

EncapsulationViolator x = new EncapsulationViolator();
object y = x.AbuseMe;
y = 17; // I have not changed x.AbuseMe

Debug.Assert(y != x.AbuseMe); // Passes!

此外,属性 getter 和 setter 允许对私有(private)字段进行适当封装,并且在功能上与将它们实现为方法相同(实际上它们是由编译器作为方法实现的)。

返回私有(private)变量可能破坏封装的一种情况是当您返回对数组的引用时:

class X
{
private int[] amazing = new int[10];

public int[] Amazing { get { return this.amazing; } }
}

X a = new X();
int[] x = a.Amazing;
int[] y = a.Amazing;

x[2] = 9;
Debug.Assert(x[2] != y[2]); // Fails!

关于c# - 一种非常常见的 C# 模式,它打破了非常基本的 OOP 原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11544356/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com