Для чего используются геттеры и сеттеры в C #?Как я могу использовать их с массивом? - PullRequest
2 голосов
/ 25 мая 2011

1) Я все еще новичок в программировании и немного читал о методах получения и установки. Но я действительно не понимаю, почему они используются. Может кто-нибудь объяснить это или указать мне статью? (Те, что я читал, были не совсем понятны для меня ...)

2) В моем текущем проекте у меня есть класс, в котором я объявляю и инициализирую массив структур. Теперь мне нужно получить доступ к массиву из другого класса, но он выдает ошибку: An object reference is required to access non-static member 'BaseCharacter.Attributes'.

Я полагаю, это может означать, что мне нужно использовать геттеры и сеттеры? Но как это работает для массивов?

Заранее спасибо!

Саймон.

РЕДАКТИРОВАТЬ: 2-й вопрос был решен, что приводит меня к чему-то еще. Когда я хочу использовать какой-то класс в другом, я делаю новый экземпляр класса, верно? И это значит, что я получу исходные значения? Но это не то, что я хочу.

Второй класс используется для генерации пользовательского интерфейса и нуждается в значениях, которые я храню в первом классе.

В какой-то момент я буду реализовывать файлы сохранения (XML или даже на сервере на более позднем этапе). Могу ли я просто получить значения из этих файлов?

Ответы [ 4 ]

6 голосов
/ 25 мая 2011

Для методов получения и установки (вещи, которые их используют, называются свойствами), это просто удобный и приятный способ заставить людей думать, что они используют переменную, но выполнять некоторые вычисления, когда переменная обновляется или к ней обращаются. , Например:

BankAccount.Interest

выглядит лучше, чем

BankAccount.GetInterest()

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

Они также используются, чтобы сделать переменную доступной вне класса, но изменяемой только из класса с помощью этой техники:

public double Interest {
    get;
    private set;
}

В качестве примера используемого установщика, если вы когда-либо использовали Windows Forms и обновляли свойство Height или Width элемента управления, вы используете установщик. Хотя похоже, что вы используете обычную переменную экземпляра, такую ​​как c.Height = 400, вы действительно позволяете c обновить ее позицию, перерисовав в новом месте. Поэтому сеттеры уведомляют вас точно, когда изменяется переменная, так что ваш класс может обновлять другие вещи на основе нового значения.

Еще одно применение свойств заключается в том, что вы можете проверить значение, которое люди пытаются установить для свойства. Например, если вы хотите сохранить процентную ставку для каждого банковского счета, но не хотите, чтобы отрицательные числа или числа превышали 50, вы просто используете установщик:

private int _interestRate = someDefault;
public int InterestRate {
    get { return _interestRate; }
    set {
        if (value < 0 || value > 50)
            throw new SomeException(); // or just don't update _interestRate
        _interestRate = value;
    }
}

Таким образом, люди не могут устанавливать публичные значения в недопустимые значения.

<ч /> По второму вопросу вы можете сделать одну из двух вещей в зависимости от того, что вы пытаетесь сделать.

Один : Вы можете сделать этого участника static. Это означает, что только один из них существует для всего класса, а не один на экземпляр класса. Тогда вы можете получить к нему доступ ClassName.MemberName.

Вы можете сделать это следующим образом:

// inside the BaseCharacter class definition:
public static SomeStruct[] Attributes = new SomeStruct[size];

// then to use it somewhere else in your code, do something with
BaseCharacter.Attributes[index]

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

Вы бы сделали это так:

BaseCharacter bc = new BaseCharacter();
// use bc.Attributes

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

3 голосов
/ 25 мая 2011

Если вы новичок в объектно-ориентированном программировании, вы можете упустить важную концепцию, касающуюся инкапсуляции.

Поля (атрибуты) класса должны быть доступны только внутри класса (или он наследуетсяклассы).То есть, если у нас есть ученик класса, только с именем, вы можете сделать

public class Person
{
    public string Name;
}

Так что в любом месте вашей программы вы сможете получить к нему доступ, выполнив:

Person person = new Person();
person.Name = "Andre";

Это работает, но не инкапсулировано.В некоторых языках, таких как C ++ или Java, это было сделано так:

public class Person
{
    private string _name;

    public string setName(string newName)
    {
        this._name = newName;
    }
    public string getName()
    {
        return this._name;
    }

    }

Person person = new Person();
person.setName("Andre");

Это делает наш атрибут _name инкапсулированным, его можно получить только с помощью методов get и set (то есть с помощью интерфейс класса).

C # делает это проще, позволяя получать и устанавливать:

public class Person
{
    private string name;
    public string Name
    {
        get { return this.name; }
        set { this.name = value; }
    }
}

Person person = new Person();
person.Name = "Andre";

Это очень похоже на второй пример (способ Java / C ++), но вы воспринимаете Name как свойство, а не методыи оставив наше имя свойства инкапсулированным

3 голосов
/ 25 мая 2011

На самом деле упомянутая вами ошибка не связана с концепцией методов получения и установки, а потому, что после создания вашего класса вам необходимо создать объект перед использованием его членов; думать о классе как о шаблоне для документа, а объект как о документе

вы, скорее всего, делаете что-то вроде этого:

var someVar = BaseCharacter.Attributes;

Когда вы должны делать что-то вроде этого:

var someVar = new BaseCharacter (); var someOtherVar = someVar.Attributes;

И о том, почему геттеры и сеттеры, Ответ Сета Карнеги это прекрасно освещает.

2 голосов
/ 25 мая 2011

1) Они могут показаться необязательными, но они позволяют вам больше контролировать код:

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

private string name;
public string Name
{
    get
    {
        // running additional code, e.g. here I avoid returning 'null' for a name not set
        if(name == null)
            return "(Unknown)";
        return name;
    }
    set
    {
        // checking incoming values, e.g. here I avoid setting an empty name
        name = value != null && value.Length > 0 ? name : null;
        // running more/additional code, e.g. here I raise an event
        if(OnNameChange)
            OnNameChange();
    }
}

2) Не зная кода, трудно сказать вам точную причину, но если вы хотите получить доступ к некоторой переменной или свойству-члену, вы должны либо создать объект этого класса, либо сделать переменную статической (например, разделенной все экземпляры объекта):

class MyClass
{
    public static int someNumber = 55;
    public int thisNumber;
}

// ...

int someothervar = MyClass.someNumber; // access the static member variable
MyClass mc = new MyClass(); // create an object of the class
int yetanothervar = mc.thisNumber; // access the member variable
...