Должны ли составные свойства класса Model всегда инициализироваться? - PullRequest
4 голосов
/ 17 марта 2011

Я пытался найти похожий вопрос на SO, но безуспешно.Извините, если это дубликат.

Каковы недостатки создания экземпляров переменных типа класса при их объявлении?

Во многих классах, представляющих модель бизнес-объектов, у нас есть такие вещи:

public class RateArea {...}
public class FlatRateSchedule 
{
    public string ScheduleID {get;set;}
    public decimal MaxAmount {get;set;}
}

public class PricingData
{
    private List<RateArea> rateAreaList = new List<RateArea>();
    private FlatRateSchedule flatRateSchedule = new FlatRateSchedule();

    public List<RateArea> RateAreaList
    {
        get { return rateAreaList; }
        set { rateAreaList = value; }
    }

    public List<FlatRateSchedule> FlatRateScheduleList
    {
        get { return flatRateScheduleList; }
        set { flatRateScheduleList = value; }
    }
}

В какой-то момент этот класс PricingData инициализирован, а некоторые свойства гидратированы (но не всегда все свойства).

Считается, что мы создаем "пустые" экземпляры классов, так что нетсвойства всегда null.Это удобно, потому что мы никогда не должны проверять, является ли какое-либо свойство нулевым, прежде чем получить доступ к его элементам.Независимо от того, являются ли свойства гидратированными или нет, они никогда не будут нулевыми для класса потребления.Если свойства не инициализированы, то код должен проверять наличие нуля каждый раз перед обращением к свойству.

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

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

Ответы [ 3 ]

3 голосов
/ 17 марта 2011

Здесь не эксперт, но

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

Вы можете использовать .Net 4.0 Lazy<T> class.

От Msdn: "Используйте экземпляр Lazy, чтобы отложить создание большого или ресурсоемкого объекта или выполнение ресурсоемкой задачи, особенно когда такое создание или выполнение можетне происходит во время жизни программы. "

Кроме этого, я думаю, что все ваши свойства будут интенсивными, чтобы быть нулевыми, и чтобы каждый потребляющий класс делал нулевые проверки.Lazy<T> решает это.

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

Пока ваши свойства являются только списками (как в вашем примере), это может быть хорошим соглашением, делающим ваш код более компактным и более легким для чтения.Списки могут быть пустыми, и если вам не нужно различать пустой список и пустую ссылку, это работает нормально.Но если ваши свойства содержат другие «Бизнес-объекты», это может не так легко работать.Зачастую создание этих «дочерних» бизнес-объектов не может или не должно выполняться во время создания «родительского» объекта.

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

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

public List<RateArea> RateAreaList
{
    get {
        rateAreaList = rateAreaList ?? new List<RateArea>(); 
        return rateAreaList; 
    }
    set { rateAreaList = value; }
}
...