C#私有成员可见性

我们的商业模式中有一个学生class。 令我感到奇怪的是,如果我们操纵另一名学生的一名学生,学生的私人成员是可见的……这让我觉得有些不雅:)

class Program { static void Main(string[] args) { Student s1 = new Student(); Student s2 = new Student(); s1.ExamineStudentsMembers(s2); } } public class Student { private String _studentsPrivateMember; public Student() { _studentsPrivateMember = DateTime.Now.Ticks.ToString(); } public void ExamineStudentsMembers(Student anotherStudent) { //this seems very wrong Console.WriteLine(anotherStudent._studentsPrivateMember); } } 

我可以对设计考虑因素/含义有所了解吗? 您似乎无法隐藏兄弟姐妹的信息。 有没有办法将字段或成员标记为隐藏在同一个类的其他实例中?

有一种简单的方法可以确保:

不要乱用同一类的其他实例的私有成员。

说真的 – 你是那个写Student代码的人。

确保这一点的最简单方法是编程到接口,例如:

 class Program { static void Main(string[] args) { IStudent s1 = new Student(); IStudent s2 = new Student(); s1.ExamineStudentsMembers(s1); } } public interface IStudent { void ExamineStudentsMembers(IStudent anotherStudent); } public class Student : IStudent { private string _studentsPrivateMember; public Student() { _studentsPrivateMember = DateTime.Now.Ticks.ToString(); } public void ExamineStudentsMembers(IStudent anotherStudent) { Console.WriteLine(anotherStudent._studentsPrivateMember); } } 

由于ExamineStudentsMembers试图访问私有字段,因此将不再编译。

如果您正在编写该类,则可以完全控制它,因此如果您不希望一个对象能够修改另一个对象,请不要编写该function。

类通常在其他实例中使用私有变量来实现有效的比较和复制function。

  • 私有只意味着只能从父类型的代码中访问成员(字段/方法/等)。 来自CSharpOnline
  • 多个实例的私有成员是可见的,可以调用。 当您在类型上实现“复制构造函数”或“克隆”方法时,这会派上用场,其中参数是相同类型的实例。 如果设计人员将私有字段设置为无法访问,那么您可能必须创建一堆getter方法, 仅用于克隆/复制以获取它们。 恕我直言,我更喜欢它的方式。 在同一类型中,读取另一个对象的状态并不像写入它那样糟糕(这对于您/您的团队来说可能是一个DONT代码约定。)

如下所示:访问兄弟的私人数据可能看似错误:

 public void ExamineStudentsMembers(Student anotherStudent) { //this seems very wrong Console.WriteLine(anotherStudent._studentsPrivateMember); } 

但是,对于需要这种function的方法来说,这似乎并不那么奇怪。 什么方法需要访问兄弟的私人数据? 比较方法(特别是等于)和数据结构中的对象(比如树或链表)。

比较方法通常直接比较私有数据而不仅仅是公共数据。

对于组成链接列表,图形或树的一类节点,能够访问兄弟的私有数据正是所需要的。 知道中的代码(类的一部分)可以修改数据结构,但数据结构之外的代码不能触及内部。

值得注意的是,这两种情况在日常编程中不如首次开发此语言function时那么常见。 早在20世纪90年代和21世纪初,在C ++中构建自定义数据结构和比较方法就更为常见。 也许现在是重新考虑私人成员的好时机。

我喜欢第二点,你可以看一下,但不要碰那些私人会员。

有趣的是,你应该说,我曾经认识一位老师,他说他经常遇到一个问题,决定哪些课程可以看成员,以及哪些课程可以让他们真正玩耍。

对象只是一个数据; 该类包含该function。 成员方法只是编译器播放的一个很好的技巧; 它更像是一个带有隐含参数的静态方法(有点像扩展方法)。 考虑到这一点,保护对象彼此没有任何意义; 你只能保护彼此的课程。 因此它以这种方式工作是很自然的。

不,这是必要的,方法代码不是特定于实例,它仅特定于对象的类型。 (虚方法)或变量的声明类型(对于非虚方法)。 另一方面,非静态字段是特定于实例的…这就是您具有实例级隔离的地方。

静态方法和非静态方法之间的唯一区别是不允许静态方法访问其他基于实例的(非静态)方法或字段。 除非强制编译器在使用基于实例的语法调用的任何地方抛出错误,否则任何可以在不修改的情况下变为静态的方法都不会受到任何影响。

如果您打算检查给定学生的信息,那么我会将方法更改为静态:

  public static void ExamineStudentsMembers(Student student) { Console.WriteLine(student._studentsPrivateMember); } 

然后,您将使用Student.ExamineStudentsMembers(s1) 。 使用s1.ExamineStudentsMembers(s2)将无效。

如果这不是预期的目的,我会将方法重写为:

  public void ExamineStudentsMembers() { Console.WriteLine(_studentsPrivateMember); } 

然后通过编写s1.ExamineStudentsMembers()来使用上面的内容。

私有成员将隐藏客户端的实现细节。 客户端应该只能看到接口(公共方法/字段/属性)。

目的不是为了保护程序员免受他自己的伤害。

这也不是安全function,因为您始终可以通过reflection访问私有字段。

这真的是分离界面和实现(黑盒设计),以及客户编程与合同(所有公共领域)。

例如,如果您有一个公共get属性,它可以直接访问某个私有字段,或者它可以从其他一些字段计算值。 目的是,客户端只知道合同(公共财产),并且可以在不影响客户的情况下更改实施

对象范围永远不会暗示安全性 – 永远! 操作系统的角色是提供运行时安全性。 设计依赖于特定于语言的对象作用域来限制运行时对象实例数据访问的系统是一个错误。 如果不是这种情况,那么根据定义,所有非OO语言都是不安全的。