Что является более правильным и почему? - PullRequest
1 голос
/ 25 марта 2011

Какая реализация лучше или нет разницы?

1.

public class Simple
{
    public IList<string> Entries { get; private set; }

    public Simple()
    {
        Entries = new List<string>();
    }
}

или 2.

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}

Ответы [ 9 ]

2 голосов
/ 25 марта 2011

Я предполагаю, что для второй версии вы имели в виду:

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}

Обратите внимание, что я сделал переменную entries только для чтения.

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

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

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

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

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

1 голос
/ 25 марта 2011

Если вы храните список в поле, вы можете пометить поле как readonly, чтобы убедиться, что вы не изменили поле внутри класса.

public class Simple
{
    private readonly IList<string> entries = new List<string>();
    public IList<string> Entries { get { return entries; } }
}
1 голос
/ 25 марта 2011

Нет реальной практической разницы (# 2 не будет компилироваться, вам нужно пропустить установщик).

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

Я бы предпочел автоматическую версию свойства, потому что (я чувствую) она немного проще, и при необходимости рефакторинг к свойству с полем поддержки.

0 голосов
/ 25 марта 2011

Первый компилируется в эквивалент этого IL в любом случае:

public class Simple{    
  private IList<string> entries;

  public IList<string> Entries { 
    get { return entries; }
  } 

  public Simple() {
    entries= new List<string>();    
  }
}

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

Это будет эквивалентно второму методу:

public class Simple{    
  private readonly IList<string> entries;

  public IList<string> Entries { 
    get { return entries; }
  } 

  public Simple() {
    entries= new List<string>();    
  }
}
0 голосов
/ 25 марта 2011

Никаких реальных отличий нет ни в API, который вы выставляете, ни в семантике в коде (хорошо, первый позволяет позже перезаписать переменную Entries, что, вероятно, вам не нужно).

Большая часть различий заключается в синтаксисе, который является лишь вопросом вкуса.

0 голосов
/ 25 марта 2011

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

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

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

Лично я использую второй только тогда, когда у меня естьreadonly переменная, и первая в противном случае (она меньше печатает).Эй, Андерс, а как насчет автоматически реализованных свойств только для чтения?

Редактировать

Отредактированный вопрос имеет гораздо более простой ответ: если поле имеет значение readonly, пометьте его как readonly.Единственный способ сделать это - это второй способ.

Не различать readonly свойства не является кардинальным грехом или чем-то еще, но это определенно менее ясно, чем различать их (и может даже помочь предотвратить некоторые ошибки).

0 голосов
/ 25 марта 2011

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

0 голосов
/ 25 марта 2011

Параметры # 1 лучше, так как в секунду вы также, вероятно, пропустили ключевое слово readonly.

0 голосов
/ 25 марта 2011

Вариант № 2 не будет компилироваться в первую очередь.

Кроме этого, в опции # 2 вы можете вообще пропустить set. Например, PropertyInfo.CanWrite return false.

...