在一个类中,我们将类成员声明为私有,但我们将属性定义为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;};
}
这背后的原因是什么?
答案 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
。否则,如果必须internal
或protected
工作,则分别为internal
或protected
。否则,如果它必须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
的情况,并且几乎所有不具有任何自定义逻辑的属性都是protected
或public
。
*或者它是private
或internal
课程,我们从外部承诺不要将其设置为愚蠢的东西,但是执行承诺比制作承诺更好如果可以的话。
答案 2 :(得分:0)
你是对的 - 属性通常用作公共属性。 虽然:您可以定义这样的属性以及:
$state
这将使其他类获得您的属性的值,但他们将无法更改它。
想象一下,如果您要开发一个类似于包含许多复杂控件的程序集的项目。如果你希望用户能够阅读,控件中有什么值,因为它被计算你给它一个公共getter但是私有的setter,因为你不希望有人操纵里面发生的事情。
答案 3 :(得分:0)
不直接设置字段,但是通过属性遵循Encapsulation的面向对象原则。这包括类是其对象包含的数据的老大。类应始终保持对其数据访问的控制(无论是读取还是写入)。有时,这意味着他们需要执行其他步骤以确保数据一致性。但即使他们不这样做,事实上不应该对呼叫者保持隐藏,因为这不属于他们的业务(分离关注)。因此,简单的规则是:没有对象数据的快捷方式。如果你想得到一些,你必须要求班级给你。在C#中,这就是属性的用途。
答案 4 :(得分:0)
使用属性并将其公开后有多种原因
将课程字段标记为公开&amp;暴露是一种风险,就像你一样 没有控制什么得到分配&amp;返回。
想要在值发生变化时进入调试器?只需在setter中添加一个断点即可。
想要记录所有访问权限吗?只需将日志记录添加到getter即可。 属性用于数据绑定;字段不是。
在私人成员上添加验证(例如,值不能设置为否定值)。
如果为null,为空或为零,则返回一些默认值。
可以将属性声明为读/写,只读或只写。
其他好处,反思和数据绑定。
答案 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; }
}