Какова цель аксессоров?

может кто-нибудь помочь мне понять get & set?
Зачем они нужны? Я могу просто сделать общедоступную переменную.

6 ответов


предупреждение: я предполагаю, что вы уже знайте об объектно-ориентированном программировании.

что are свойства?

свойства являются языковыми элементами, которые позволяют избежать повторяющихся getXYZ() аксессоры и setXYZ() методы мутаторов, найденные на других языках, таких как Java.

почему они существуют?

они направлены на решение следующих проблемы:

  1. слова 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 стать довольно раздражающим.

  2. предоставление прямого доступа к фактической переменной прерывает инкапсуляцию, так что это не выбор.

как они используются?

они используется так же, как переменные. Вы читаете / пишете им так же, как переменные.

как они создавались?

они создано методы. Вы определяете пару методов, которые:

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

другие Примечания:

автоматически реализуемые свойства

в 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#)
  • несколько геттеров или сеттеров (не на C#)
  • и так далее

Они называются Аксессорами

метод доступа к свойству содержит исполняемые операторы, связанные с получением (чтением или вычислением) или установкой (записью) свойства. Объявления доступа могут содержать метод доступа 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 Вы можете сделать это намного проще через auto-properties

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


свойства действуют как аксессоры к внутреннему состоянию объекта,скрытие реализации этого государства.

Так, например, у вас может быть свойство first name в классе

public class Example
{
    private string firstName;

    public string FirstName
    {
        get {return this.firstName;}
    }
}

поэтому любому, кто использует класс, не нужно знать, как хранится первое имя, они просто знают, что могут получить его строковое представление. Добавляя набор, Вы также добавляете мутатор, что изменения объектов внутреннего государство

public class Example
{
    private string firstName;

    public string FirstName
    {
        get {return this.firstName;}
        set {set this.firstName = value;}   
    }
}           

снова вы все еще изолируете, как первое имя хранится внутри (инкапсуляция), но пользователи могут изменить его, передав в строку.


проще говоря, get и set аксессоры-это функции, вызываемые свойством; то есть, когда вы извлекаете значение или когда вы его устанавливаете. Это заставляет тип поведения на пути значения извлекаются или устанавливаются.

например, вы можете иметь механизм для получения / установки паролей. Вообще говоря, вы только захотите сравнить хэш пароля вместо хранения вещей открытым текстом, поэтому у вас будет переменная getter, извлекающая сохраненный хэш, и сеттер будет возьмите предоставленные входные данные и хэшируйте их для хранения.

вот что я имею в виду:

public class User {
    //Usery properties here, and...
    private string _password;
    public string Password {
        get {
            return _password;
        }
        set {
            _password = SomeHashingFunction(value);
        }
    }
}

value - переменная, предоставленная сеттеру из того, что было дано в назначении переменной. например: someuser.Password = "blah";


Get и set используются в свойствах. Каждый из них может быть public, protected или Private. Подобно методам accessor и mutator, они позволяют некоторые вычисления, когда код пытается получить доступ/мутировать свойство. Конечно, пока вы определяете один из 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{} are аксессоры, которые предлагают возможность легко читать и писать к закрытым полям. Работа с простым примером:

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 является публичным свойством, которое имеет геттер и сеттер это позволяет получить доступ к закрытому полю _bar, который в противном случае был бы недоступен за пределами класса Foo.

теперь в классе, который имеет instace Foo, вы можете сделать следующее:

public class IHasAFoo()
{
    private Foo _myFoo = new Foo();

    public void SomeMethod()
    {
        _myFoo.Bar = 42;
    }
}

Так публика accessor позволяет установить значение частного поля обратно в Foo.

надеюсь, что это поможет!