时间:2011-07-01 23:47:53

标签: c# class properties accessor

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

6 个答案:

答案 0 :(得分:24)

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

属性是什么?

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

为什么它们存在?

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

  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; }
    }
    

    然后一直说:

    if (person.getAge() > blah || person.getAge() < 10)
    {
        person.setAge(5);
    }
    

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

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

  3. 他们是如何使用的?

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

    他们是如何创建的?

    创建作为方法。您定义了一对方法:

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

      class Person
      {
          private int _age; //Declare the backing field
      
          public int Age
          {
              get { return this._age; }
              set { ... }
          }
      }
      
    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;
              }
          }
      }
      
    3. 其他说明:

      自动实施的属性

      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;,这相当于调用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!
      

      不是很整洁吗? :)

      还有别的吗?

      属性还有很多其他功能,但并非所有功能都可以在C#中使用:

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

答案 1 :(得分: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; 
   }
}
  

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

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

答案 2 :(得分:4)

答案 3 :(得分:1)

简单地说,getset访问器是在属性上调用的函数;也就是说,当您检索值或设置它时。它会在检索或设置值的方式上强制执行某种行为。

例如,您可能希望有一种获取/设置密码的机制。一般来说,你只想比较密码的哈希值而不是存储明文的内容,所以你要让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";

答案 4 :(得分:1)

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中设置私有字段的值。

希望有所帮助!

答案 5 :(得分:1)