Правильное использование свойств C #

private List<Date> _dates;

public List<Date> Dates
{
    get { return _dates; }
    set { _dates = value; }
}

OR

public List<Date> Dates
{
    get;        
    set;    
}

I have always used the former, is that incorrect or bad practice? It never occurred to me that I could just use the second option. I do like having my encapsulated variables to begin with an underscore so I can distinguish them from method parameters. And I've just always done it that way.

Is it possible that using the first option would result in an extra List object being instantiated and then the whole of _dates being replaced with value, or is it more intelligent than that?

Also, which is the most prominent in industry or is it totally subjective?

13
задан Nobody 20 August 2010 в 14:53
поделиться

12 ответов

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

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

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

Второй синтаксис был введен в C # 3.0. Так что первый вариант будет более совместим со старыми компиляторами.

7
ответ дан 1 December 2019 в 18:54
поделиться

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

Э. (Очень плохой пример)

    private int _limit;
    private int _onHand;
    private bool returnToVendor;

    public Item(int limit, int onHand)
    {
       _limit = limit;
       _onHand = onHand;
    }

    public int ReturnStock
    {
       get
       {
         if(_onHand > _limit)
         {
            returnToVendor = true;
            return _onHand;
         }
       }

       set
       {
           _onHand = value;

           if(_onHand < _limit)
           {
              returnToVendor = false;
           }
       }
    }
1
ответ дан 1 December 2019 в 18:54
поделиться

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

Если вам нужна ее инициализация, вам нужно перейти к первой версии ...

private List<Date> _dates; 

public List<Date> Dates 
{ 
    get { if (_dates == null) _dates = new List<Date>(); return _dates; } 
    set { _dates = value; } 
} 
0
ответ дан 1 December 2019 в 18:54
поделиться

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

0
ответ дан 1 December 2019 в 18:54
поделиться

Эти два компонента компилируются примерно одинаково (я не знаю, будет ли имя вспомогательного поля точно таким же, но они будут функционально эквивалентны).

IIRC, возможность делать автоматические свойства ( public List Dates {get; set;} ) была добавлена ​​либо в .NET 3.0, либо в 3.5.

0
ответ дан 1 December 2019 в 18:54
поделиться

Оба в основном одинаковы из-за того, как .NET компилирует автоматические свойства. Автоматические свойства стали доступны в .NET 3.5.

7
ответ дан 1 December 2019 в 18:54
поделиться

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

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

public List Dates
{
    get;
    private set;
}

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

1
ответ дан 1 December 2019 в 18:54
поделиться

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

Почти все мои объявления свойств выглядят так:

public bool IsBlah { get; private set; }

Это делает его красивым, читаемым и защищенным геттером.

Но бывают случаи, когда вам нужно явное защитное поле:

private bool? _isBlah;
public bool IsBlah
{
    get
    {
        if (_isBlah == null)
        {
            // Do something expensive here and set _isBlah
            _isBlah = true;
        }
        return _isBlah;
    }
}
4
ответ дан 1 December 2019 в 18:54
поделиться

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

private IList<DateTime> _dates;

public MyClass() {
    _dates = new List<DateTime>();
}

public IList<DateTime> Dates {
    get {
        return _dates;
    }
}

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

Однако в вашем примере вам нужно использовать только первый подход, если вам нужна какая-то логика при получении или установке свойства. В противном случае автоматические свойства делают то же самое, что и вы, только получают и устанавливают значение для частного поля. Кроме того, {get; набор; } улучшает читаемость и помогает другим программистам понять ваши намерения, с моей скромной точки зрения.

Например:

public class MyClass {
    private IList<DateTime> _dates;

    public IList<DateTime> Dates {
        get {
            return _dates;
        } set {
            _dates = value;
        } 
    }
}

против

public class MyClasse {
    public IList<DateTime> Dates { get; set; }
}

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

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

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

0
ответ дан 1 December 2019 в 18:54
поделиться

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

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

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

public class MyClass
{

  public List<Date> Dates
  {
      get;        
      set;    
  }

  public MyClass()
  {
      Dates = new List<Date>();
  }

}
1
ответ дан 1 December 2019 в 18:54
поделиться

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

0
ответ дан 1 December 2019 в 18:54
поделиться

Используйте первый вариант, если вам нужно добавить какую-то логику к геттеру/сеттеру.

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

public List<Date> Dates { get; private set; }

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

private List<Date> _dates = new List<Date>();
private ReadOnlyCollection<Date> _readOnlyDates =
    new ReadOnlyCollection<Date>(_dates);

public ReadOnlyCollection<Date> Dates
{
    get { return _readOnlyDates; }
}
19
ответ дан 1 December 2019 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: