Доступ к членам в вашем собственном классе: использовать (авто) свойства или нет? - PullRequest
2 голосов
/ 22 января 2010

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

Если у вас есть класс с переменными экземпляра, и вы также создали свойства, которые являются просто геттерами и сеттерами для этих переменных экземпляра, следует ли вам использовать свойства внутри вашего собственного класса или всегда следует использовать переменную экземпляра?

Наличие авто-свойств в C # 3.0 сделало это решение еще сложнее.

Использование свойств:

public class MyClass
{
    private string _name;

    // could be an auto-property of-course
    public string Name { get { return _name; } set { _name = value; } }

    public void Action()
    {
        string localVar = Name;
        // ...
        Name = "someValue";
        // ...
    }
}

Использование переменных экземпляра:

public class MyClass
{
    private string _name;

    public string Name { get { return _name; } set { _name = value; } }

    public void Action()
    {
        string localVar = _name;
        // ...
        _name = "someValue";
        // ...
    }
}

(для тех, кто ненавидит префиксы членов, я прошу прощения)

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

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

Есть ли веские причины для выбора того или другого?

Ответы [ 6 ]

2 голосов
/ 22 января 2010

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

http://blogs.msdn.com/ericlippert/archive/2009/01/14/automatic-vs-explicit-properties.aspx

1 голос
/ 22 января 2010

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

Сложно объяснить, но рассмотрим следующие выражения:

mTotalPrice = mPrice * mQuantity;

mTotalPrice = Price * Quantity;

Что делать во втором выражении, если мне нужно изменить внутренние компоненты, чтобы выразить все цены в € вместо $ (не затрагивая общедоступный интерфейс, который все еще использует $)?

Одно решение состоит в том, чтобы сделать выражение более сложным, добавив противоположное изменение в свойстве.

mTotalPrice = Price / Rate * Quantity

Другое решение состоит в том, чтобы вместо этого начать использовать личное поле.

mTotalPrice = mPrice * Quantity

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

1 голос
/ 22 января 2010

Я также всегда использую переменные экземпляра. Причина в том, что свойства могут выполнять такие вещи, как проверка аргументов (например, в установщике), если они не нулевые или не пустые. Если вы используете переменную внутри кода вашего класса, нет необходимости проходить дополнительные накладные расходы на эти проверки (при условии, что вы знаете, что значение переменной является действительным). Свойства могут также выполнять другие функции (например, протоколирование), которые важны для общедоступного API, но не для внутреннего использования, поэтому, опять же, лучше избегать накладных расходов и просто использовать переменную экземпляра, на мой взгляд.

0 голосов
/ 22 января 2010

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

Я решил вместо этого использовать свойства public или private, чтобы обернуть переменную экземпляра. Это означает, что мне нужно только поставить точку останова в получателе / ​​установщике свойства, если мне нужно отладить проблему с переменной экземпляра, вместо того, чтобы (потенциально) разбить множество точек останова по всему коду.

0 голосов
/ 22 января 2010

Я думаю, что нет никакой разницы между этими двумя подходами.

Автоматически реализованные свойства - это просто быстрый способ доступа к закрытым элементам, которые создаются любым способом.

Пример из MSDN :

class Customer
{
    // Auto-Impl Properties for trivial get and set
    public double TotalPurchases { get; set; }
    public string Name { get; set; }
    public int CustomerID { get; set; }

    // Constructor
    public Customer(double purchases, string name, int ID)
    {
        TotalPurchases = purchases;
        Name = name;
        CustomerID = ID;
    }
    // Methods
    public string GetContactInfo() {return "ContactInfo";}
    public string GetTransactionHistory() {return "History";}

    // .. Additional methods, events, etc.
}
0 голосов
/ 22 января 2010

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

Public String MyString
{
   { get { return this.MyString; } }  //<== Stack Overflow
   { set { this.myString = value; } } 

}
private String myString;
...