C # Accessors и Коллекции - PullRequest
       1

C # Accessors и Коллекции

4 голосов
/ 23 декабря 2010

При определении классов я выставляю членов класса как свойства в соответствии с:

class ClassA
{
    private String _Name;

    public String Name
    {
        get { return _Name; }
        set { _Name = value; }
    }
 }

Какова наилучшая практика работы с коллекциями в классах в отношении средств доступа

Так что, если класс расширен до чего-то вроде:

class ClassA
{
    private String _Name;
    private List<String> _Parts = new List<String>();

    public String Name
    {
        get { return _Name; }
        set { _Name = value; }
    }
 }

Как мне выставить следующий предмет?

Ответы [ 8 ]

4 голосов
/ 23 декабря 2010

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

public IList<String> Parts { get; private set; }
2 голосов
/ 23 декабря 2010

Соглашения об именах, с которыми я столкнулся, рекомендуют

private String _name;

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

public string Name {get; set;}

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

public void Add(...
public void Remove(...

В противном случае вы можете сделать это только для чтения с автоматическим свойством

public IList<string> Parts {get; private set;}
1 голос
/ 23 декабря 2010

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

public List<String> Parts
{
    get { return _Parts; }
    private set { _Parts = value; }
}

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

Однако, если вам нужно отправлять события при добавлении и удалении элементов, у вас есть только две опции:

  • Использовать подкласс Listкоторый отправляет события, когда это уместно
  • Не раскрывайте список вообще, а просто выставляйте AddPart(), RemovePart() и ListParts() (который возвращает копию текущего списка).

Если ваши потребности просты, просто выставьте собственность (но защитите ее от присвоения null).В противном случае вам придется немного повеселиться.

1 голос
/ 23 декабря 2010

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

public List<String> Parts { get; private set; }

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

private List<String> _Parts;
public IList<String> Parts
{
    get
    {
        if (_Parts == null)
            _Parts = new List<String>();
        return _Parts;
    }
    private set
    {
        if (value != null)
            _Parts = value;
    }
}

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

public void AddPart(String part);
public void RemovePart(String part);
public String GetPart(int index);
public IEnumerable<String> GetAllParts()
{
    foreach(String part in _Parts)
        yield return part;
}
0 голосов
/ 23 декабря 2010

Обычно мы делаем следующее:

private Collection<String> _parts = new Collection<String>();
public Collection<String> Parts {
  get { return _parts; }
}

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

0 голосов
/ 23 декабря 2010

У вас есть куча вариантов, и это действительно зависит от того, какие операции вы хотите открыть для публичного API вашего класса.Наиболее распространенные подходы:

  • Предоставляет свойство только для чтения, чтобы возвращать фактический экземпляр коллекции с той же информацией типа.
  • Предоставляет свойство только для чтения, которое возвращает интерфейс IEnumerable.
  • Предоставьте свойство только для чтения, которое возвращает обертку ReadOnlyCollection коллекции.

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

0 голосов
/ 23 декабря 2010

Я бы тоже выставил как собственность

public List<string> Parts { get; set; }
0 голосов
/ 23 декабря 2010

Не могли бы вы просто сделать то же самое - но для списка?

public List<String> parts
    {
        get { return _Parts; }
        set { _Parts = value; }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...