autoproperties в c # ленивая загрузка? - PullRequest
3 голосов
/ 14 января 2012

Я немного читал о отложенной загрузке в c #, и это может показаться очень простым вопросом, но мне интересно, являются ли autoproperties отложенной загрузкой по умолчанию. Eg.:

public Color MyColor { get; set; }

Или я должен был бы реализовать что-то вроде

private Color _color;
public Color MyColor
{
  get
  {
      if(_color==null)
      { 
       _color=new Color("red");
      }
      return _color;
  }
 }

Спасибо Томас

Ответы [ 5 ]

5 голосов
/ 14 января 2012

Авто свойства просто получают вспомогательное поле, сгенерированное компилятором.

Итак, это:

public Color MyColor { get; set; }

Будет так:

private Color _color;
public Color MyColor
{
  get
  {
      return _color;
  }

  set
  {
      _color = value;
  }
 }

Так что они не загружаются лениво - вам нужно будет реализовать это самостоятельно.

Вы можете создать поле поддержки следующим образом:

private Color _color = new Color("red");

С автоматическими свойствами вы можете установить значение по умолчанию, используя конструктор:

// in the constructor:
MyColor = new Color("red");
2 голосов
/ 14 января 2012

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

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

private Lazy<Color> _color = new Lazy<Color>(() => new Color("red"));
public Color MyColor
{
  get
  {
      return _color.Value;
  }
}

Что в этом случае просто сложнее, но в некоторых других случаях проще.

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

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

public Color MyColor
{
  get
  {
    if(_color == null)
    {
      var c = new Color("red");//allow multiple creations but...
      Interlocked.CompareExchange(ref _color, c, null);//only one write
    }
    return _color;
  }
}

public Color MyColor
{
  get
  {
    if(_color == null)
      lock(somelock)
        if(_color == null)
          _color = new Color("red");//allow one creation only
    return _color;
  }
}

С Lazy<Color> существует форма конструктора, которая принимает значение LazyThreadSafetyMode, указывающее, какой подход вы хотите.

2 голосов
/ 14 января 2012

Нет, они не ленивые, автоматическое свойство такое же, как при этом

private Color _color;
public Color MyColor
{
  get
  {
      return _color;
  }
  set 
  {
      _color = value;
   }
 }
0 голосов
/ 14 января 2012

Свойства

public Color MyColor { get; set; }  

Плюсы:

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

Минусы:

  • Ужасно с отладчиком.С каким именем переменной связано это свойство?Надеюсь, Microsoft автоматически использовала _MyColor, но это вполне может быть что-то загадочное.

Поля

public Color MyColor;  

Плюсы:

  • Нет сложности
  • Простота использования с отладчиком

Минусы:

  • Я не могу сразу подумать, как получить и установить значения для этого с помощью отражения.Если это возможно, то в этом нет никаких недостатков по сравнению с Lazy Property.

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

0 голосов
/ 14 января 2012

Если вы напишите

public Color MyColor { get; set; }

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

this.MyColor = new Color("red");

Авто-свойства - это просто ярлык.

public Color MyColor { get; set; }

в том же виде, что и

private Color _MyColor;
public Color MyColor
{
    get
    {
        return this._MyColor;
    }

    set
    {
        this._MyColor = value;
    }
}
...