为什么集体成员私有和财产公开?

时间:2016-11-18 11:56:50

标签: c#

在一个类中,我们将类成员声明为私有,但我们将属性定义为public。

例如:

public class student
{
    private int StudentId;
    private string StudentName;
    private string Address;
} 

然后我们分配使用方法。

但是如果我们使用get set属性定义public就像。

public class student
{
    public int StudentId {get;set;};
    public string StudentName{get;set;};
    public string Address{get;set;};
} 

这背后的原因是什么?

6 个答案:

答案 0 :(得分:1)

一个班级需要控制其公共成员的行为:即控制他们的行为

想象一下,例如private string StudentName;是否public被外部代码(类student之外)使用了StudentName。然后你决定要添加一个验证来限制StudentName的长度 - 你怎么能这样做?您必须在代码中找到所有实例(以及可能使用此类的其他人的代码),这些实例设置public string Student {get; set;}的值并在那里添加验证。

如果您使用的是private string _student; public string Student { get { return _student; } set { if(value.Length <= 20) _student = value; } ,则不会 - 您可以通过验证轻松将其更改为显式属性:

public int StudentId {get; private set;}

即。使用属性可以更容易地从类中控制类成员的行为,从而维护封装和抽象

答案 1 :(得分:1)

那不太好。真正的规则是:

  

尽可能限制地定义所有成员。

所以,如果它可以是private那么它是private。否则,如果必须internalprotected工作,则分别为internalprotected。否则,如果它必须protected internal起作用,那么它就是protected internal。否则它是public,因为它必须public才能工作(在程序集之外的某些东西不能从它继承而必须访问它。

现在,尽管如此,我们通常会拥有大多数private字段和大多数public属性。

让我们考虑一下我们是否有public字段。这有效,将起作用,甚至在非常有限的情况下也很有用。然而,它也更脆弱。拥有它public允许任何其他代码将其设置为任何值,无论多么愚蠢。这没关系,因为当我们创建一个字段public时,我们会说&#34;没有愚蠢的值&#34;。*

但是,如果我们突然意识到有一些愚蠢的值,或者我们需要在每次更改字段时执行某些操作,或者我们需要使用某些仅属性的数据绑定。在这里,我们必须将这个领域变成一个属性,而这是一个突破性的变化;任何使用这个类的代码都必须重新编译,如果我们是唯一一个使用该类的人,那么这不是什么大不了的事,但如果它是在一个库中被使用的话其他

如果它曾是某个属性,那么我们只需将自动属性{ get; set; }转换为具有自定义实现{ get { /* do stuff and return value */ } set { /* do stuff */ } }的属性。从课堂外看,似乎什么都没有改变,我们没有破坏任何东西。

因此,99.99%的时间如果您要创建字段public,那么您最好使用该字段,以防万一。

另一方面,如果我们的private属性没有逻辑,那么getter和setter方法不会给我们任何好处。不会有任何成本,但它们毫无意义。所以我们只使用一个字段。如果我们最终不得不在未来使用私有财产而不重要,因为唯一需要重新编译的代码就是所讨论的类,我们无论如何都在重新编译它。

因此,我们最终会遇到几乎所有字段都为private的情况,并且几乎所有不具有任何自定义逻辑的属性都是protectedpublic

*或者它是privateinternal课程,我们从外部承诺不要将其设置为愚蠢的东西,但是执行承诺比制作承诺更好如果可以的话。

答案 2 :(得分:0)

你是对的 - 属性通常用作公共属性。 虽然:您可以定义这样的属性以及:

$state

这将使其他类获得您的属性的值,但他们将无法更改它。

想象一下,如果您要开发一个类似于包含许多复杂控件的程序集的项目。如果你希望用户能够阅读,控件中有什么值,因为它被计算你给它一个公共getter但是私有的setter,因为你不希望有人操纵里面发生的事情。

答案 3 :(得分:0)

不直接设置字段,但是通过属性遵循Encapsulation的面向对象原则。这包括类是其对象包含的数据的老大。类应始终保持对其数据访问的控制(无论是读取还是写入)。有时,这意味着他们需要执行其他步骤以确保数据一致性。但即使他们不这样做,事实上不应该对呼叫者保持隐藏,因为这不属于他们的业务(分离关注)。因此,简单的规则是:没有对象数据的快捷方式。如果你想得到一些,你必须要求班级给你。在C#中,这就是属性的用途。

答案 4 :(得分:0)

使用属性并将其公开后有多种原因

  1. 将课程字段标记为公开&amp;暴露是一种风险,就像你一样 没有控制什么得到分配&amp;返回。

  2. 想要在值发生变化时进入调试器?只需在setter中添加一个断点即可。

  3. 想要记录所有访问权限吗?只需将日志记录添加到getter即可。 属性用于数据绑定;字段不是。

  4. 在私人成员上添加验证(例如,值不能设置为否定值)。

  5. 如果为null,为空或为零,则返回一些默认值。

  6. 可以将属性声明为读/写,只读或只写。

  7. 其他好处,反思和数据绑定。

答案 5 :(得分:0)

在这个最简单的情况下没有特殊原因。但是如果你进一步开发 - 它将变得非常清楚:你需要从实现中抽象出来并分离出一个接口,例如:只是在单元测试中模拟学生。所以,从长远来看,你宁愿需要接口和属性,从一开始就以一种可模拟和可测试的方式编写它只是一种习惯

public interface IStudent
{
    int StudentId { get; set; }
    string StudentName { get; set; }
    string Address { get; set; }
}

public class Student : IStudent
{
    public int StudentId { get; set; }
    public string StudentName { get; set; }
    public string Address { get; set; }
}