访问者的目的是什么?

Mas*_*tic 16 c# properties class accessor

有人可以帮我理解get&set
他们为什么需要?我可以创建一个公共变量.

Meh*_*dad 25

警告:我假设您已经了解面向对象编程.

什么物业?

属性是语言元素,允许您避免使用其他语言(如Java)中的重复getXYZ()访问setXYZ()器和更改器技术.

它们为什么存在?

他们的目标是解决以下问题:

  1. getset在值的每次访问或突变的开始是讨厌,喧宾夺主.

    在Java中,您经常说:

    class person
    {
        private int _age;
        public void setAge(int value) { /*check value first, then set _age*/ }
        public int getAge() { return this._age; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    然后一直说:

    if (person.getAge() > blah || person.getAge() < 10)
    {
        person.setAge(5);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    一段时间后,getset变得相当烦人.

  2. 提供对实际变量的直接访问可以打破封装,因此这不是一个选项.

它们是如何使用的?

它们就像变量一样使用 .您可以像变量一样读/写它们.

它们是如何创建的?

它们是作为方法创建的.您定义了一对方法:

  1. 返回属性的当前值.通常情况下,这只不过是以下内容:

    class Person
    {
        private int _age; //Declare the backing field
    
        public int Age
        {
            get { return this._age; }
            set { ... }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 设置属性的值:

    class Person
    {
        public int Age
        {
            get { ... }
            set
            {
                if (value < 0) //'value' is what the user provided
                { throw new ArgumentOutOfRangeException(); } //Check validity
                this._age = value;
            }
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

其他说明:

自动实现的属性

C#3.0引入了自动实现的属性:

public int Age { get; set; }
Run Code Online (Sandbox Code Playgroud)

这相当于:

private int _age; //The name is auto-generated
public int Age { get { return this._age; } set { this._age = value; } }
Run Code Online (Sandbox Code Playgroud)

它为什么存在?

它可以帮助您避免破坏客户端可执行文件的更改.

假设你是懒惰的,不想输入整个内容,并决定公开公开变量.然后创建一个可读取或写入该字段的可执行文件.然后你改变主意并决定你实际上需要一个属性,所以你把它改成一个.

怎么了?

依赖可执行文件中断,因为代码不再有效.

自动实现的属性可帮助您避免这种情况,而无需在初始代码中增加额外冗余.

索引

索引器扩展属性语法以允许您索引对象(惊喜!),就像数组一样.
对于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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你就像使用它们一样obj[5] = 10;,这相当于调用了索引器的set方法obj.
事实上,System.Collections.Generic.List<T>索引:

var list = new List<int>();
list.Add(10);
list[0] = 5;  //You're indexing list, as though it were an array!
Run Code Online (Sandbox Code Playgroud)

这不是很整洁吗?:)

还要别的吗?

属性还有很多其他功能,但C#中并不是所有这些功能都可用:

  • 参数化属性,其中索引器是一种特殊类型
  • Getter/setter访问修饰符(在C#中)
  • 多个getter或setter(不在C#中)
  • 等等

  • 这很有趣,每一个得到任何投票的答案,也都会减少选票.:-s (2认同)
  • @Ken:不要担心我的时间,如果我们不想回答我们就不会在这个网站上.:)是的,你仍然改变了价值.但是当你使用属性时,你可以对值执行任意检查*,当你没有*any*控制暴露字段时会发生什么.这是一个很大的不同. (2认同)

Cha*_*ell 5

它们被称为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; 
   }
}
Run Code Online (Sandbox Code Playgroud)

set访问器类似于返回类型为void的方法.它使用名为value的隐式参数,其类型是属性的类型.

private m_Name;
public string Name {
    get {
        return m_Name;
    }
    set {
        m_Name = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在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
Run Code Online (Sandbox Code Playgroud)

http://msdn.microsoft.com/en-us/library/bb384054.aspx