访问者的目的是什么?
有人可以帮我理解get
& set
吗?
他们为什么需要? 我可以做一个公共变量。
警告 :我假设您已经了解面向对象编程 。
什么是物业?
属性是语言元素,允许您避免使用其他语言(如Java getXYZ()
的重复getXYZ()
访问器和setXYZ()
mutators技术。
它们为什么存在?
他们的目标是解决以下问题:
-
在每次访问或值的变异开始时说
get
和set
是令人烦恼和分散注意力的。在Java中,您经常说:
class person { private int _age; public void setAge(int value) { /*check value first, then set _age*/ } public int getAge() { return this._age; } }
然后一直说:
if (person.getAge() > blah || person.getAge() < 10) { person.setAge(5); }
过了一会儿,
get
和set
变得相当烦人。 -
提供对实际变量的直接访问会打破封装,因此这不是一个选项。
它们是如何使用的?
它们就像变量一样 使用 。 您可以像变量一样读/写它们。
它们是如何创建的?
它们是作为方法创建的 。 您定义了一对方法:
-
返回属性的当前值。 通常情况下,这只不过是以下内容:
class Person { private int _age; //Declare the backing field public int Age { get { return this._age; } set { ... } } }
-
设置属性的值:
class Person { public int Age { get { ... } set { if (value < 0) //'value' is what the user provided { throw new ArgumentOutOfRangeException(); } //Check validity this._age = value; } } }
其他说明:
自动实现的属性
C#3.0引入了自动实现的属性:
public int Age { get; set; }
这相当于:
private int _age; //The name is auto-generated public int Age { get { return this._age; } set { this._age = value; } }
它为什么存在?
它可以帮助您避免破坏客户端可执行文件的更改 。
假设你很懒,不想输入整个内容,并决定公开公开变量。 然后创建一个可读取或写入该字段的可执行文件。 然后你改变主意并决定你实际上需要一个属性,所以你把它改成一个。
怎么了?
依赖可执行文件中断,因为代码不再有效。
自动实现的属性可帮助您避免这种情况,而无需在初始代码中添加额外冗余。
索引
索引器扩展属性语法,让你索引对象(惊喜!),就像数组一样。
对于C ++用户:这类似于重载operator []
。
例:
private int[] _elements; public int this[int index] //Indexed property { get { return this._elements[index]; } set { //Do any checks on the index and value this._elements[index] = value; } }
然后你就像obj[5] = 10;
那样使用它们obj[5] = 10;
,这相当于调用obj
的索引器的set
方法。
实际上, System.Collections.Generic.List
被编入索引:
var list = new List(); list.Add(10); list[0] = 5; //You're indexing list, as though it were an array!
那不是很整洁吗? 🙂
还要别的吗?
属性还有很多其他function,但C#中并不是所有这些function都可用:
- 参数化属性,其中索引器是一种特殊类型
- Getter / setter访问修饰符(在C#中)
- 多个getter或setter(不在C#中)
- 等等
它们被称为Accessors
属性的访问器包含与获取(读取或计算)或设置(写入)属性相关联的可执行语句。 访问器声明可以包含get访问器,set访问器或两者。 get访问器的主体类似于方法的主体。 它必须返回属性类型的值。
http://msdn.microsoft.com/en-us/library/w86s7x04.aspx
private string m_Name; // the name field public string Name // the Name property { get { return m_Name; } }
set访问器类似于返回类型为void的方法。 它使用名为value的隐式参数,其类型是属性的类型。
private m_Name; public string Name { get { return m_Name; } set { m_Name = value; } }
然后在C#3的化身中,您可以通过自动属性更轻松地完成这项工作
public string Name {get; set; } // read and write public string Name {get; } // read only public string Name { get; private set; } //read and parent write
属性充当对象内部状态的访问者 , 隐藏该状态的实现 。
因此,例如,您可能在类中具有名字属性
public class Example { private string firstName; public string FirstName { get {return this.firstName;} } }
所以使用该类的任何人都不需要知道如何存储名字,他们只知道他们可以得到它的字符串表示。 通过添加一个集合,您还可以添加一个更改对象内部状态的mutator
public class Example { private string firstName; public string FirstName { get {return this.firstName;} set {set this.firstName = value;} } }
您仍然可以隔离内部存储名字的方式( 封装 ),但用户可以通过传入字符串来更改它。
简单地说, get
和set
访问器是在属性上调用的函数; 也就是说,当您检索值或设置它时。 它会在检索或设置值的方式上强制执行某种行为。
例如,您可能希望有一种获取/设置密码的机制。 一般来说,您只想比较密码的哈希值而不是存储明文的内容,因此您必须使用getter变量检索存储的哈希值,并且setter将获取提供的输入并将其哈希存储。
这就是我的意思:
public class User { //Usery properties here, and... private string _password; public string Password { get { return _password; } set { _password = SomeHashingFunction(value); } } }
value
是从变量赋值中给出的setter提供的变量。 例如: someuser.Password = "blah";
获取和设置用于属性。 他们每个人都可以是公共的,受保护的或私人的。 与accessor和mutator方法类似,当代码尝试访问/ mutate属性时,它们允许一些计算。 当然,只要你定义一个get / set,另一个是可选的。
没有属性的示例:
private int test; public int getTest() { // some computation on test here, maybe? return test; } private void setTest(int test) { // some error/range checking, maybe? this.test = test; }
有财产:
private int test; public int Test { get { // some computation on test here, maybe? return test; } private set { // some error/range checking, maybe? test = value; // value is a keyword here } }
get {}和set {}是访问器 ,提供了轻松读取和写入私有字段的能力。 使用一个简单的例子:
public class Foo() { //Field private int _bar; //Property public int Bar { get { return _bar; } set { _bar = value; } //value is an implicit parameter to the set acccessor. //When you perform an assignment to the property, the value you //assign is the value in "value" } }
在这种情况下,Bar是一个公共属性,它有一个getter和一个setter ,允许访问私有字段_bar,否则将无法在类Foo之外访问。
现在在一个有Foo实例的类中,你可以这样做:
public class IHasAFoo() { private Foo _myFoo = new Foo(); public void SomeMethod() { _myFoo.Bar = 42; } }
因此,公共访问器允许您在Foo中设置私有字段的值。
希望有所帮助!