Как вы поддерживаете свои поля поддержки?(Стили / Шаблоны) - PullRequest
2 голосов
/ 09 ноября 2009

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

В идеальном мире (мнение) вы могли бы сделать что-то вроде

class MyClass {
  ... stuff ... 

  public string MyProperty {
    private string _myBackingField = "Foo";

    get { return _myBackingField; }
    set { _myBackingField = value; }
  }
}

вместо

class MyClass {
  private string _myBackingField = "Foo";

  ... stuff ...

  public string MyProperty {       
    get { return _myBackingField; }    
    set { _myBackingField = value; }
  }
}

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

Ответы [ 6 ]

5 голосов
/ 09 ноября 2009

Я все еще предпочитаю

class MyClass {
  private string _myBackingField = "Foo";
  private string _myOtherBackingField = "bar";

  ... stuff ...

  public string MyProperty {       
    get { return _myBackingField; }    
    set { _myBackingField = value; }
  }
  public string MyOtherProperty {       
    get { return _myOtherBackingField; }    
    set { _myOtherBackingField = value; }
  }
}

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

class MyClass {

  private string _myBackingField = "Foo";
  public string MyProperty {       
    get { return _myBackingField; }    
    set { _myBackingField = value; }
  }
  private string _myOtherBackingField = "bar";
  public string MyOtherProperty {       
    get { return _myOtherBackingField; }    
    set { _myOtherBackingField = value; }
  }
}
5 голосов
/ 09 ноября 2009

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

Если вам не нравится объявлять переменные в верхней части, ближе всего я видел ваш "идеальный" стиль:

private int _integer1 = 0;
public int Integer1 
{
    get {return _integer1;}
    set {_integer1 = value;}
}
1 голос
/ 10 ноября 2009

Что я предпочитаю:

public int Integer1 
{
    get {return _integer1;}
    set {_integer1 = value;}
}
private int _integer1 = 0;

Почему?

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

это

private int _integer1 = 0;
///<summary>
/// this is my property, enjoy it
///</summary>
public int Integer1 
{
    get {return _integer1;}
    set {_integer1 = value;}
}

или

///<summary>
/// this is my property, enjoy it
///</summary>
public int Integer1 
{
    get {return _integer1;}
    set {_integer1 = value;}
}
private int _integer1 = 0;

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

1 голос
/ 09 ноября 2009

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

class MyClass 
{  
    ... stuff ...   
    public string MyProperty 
    {    
        private string _myBackingField;    
        get 
        { 
            if (_myBackingField == null)
            {
                myBackingField = ... load field ...;
            }
            return _myBackingField; 
        }    
        set { _myBackingField = value; }  
    }
}

На самом деле я поднял это как предложение по Microsoft Connect некоторое время назад.

1 голос
/ 09 ноября 2009

Зачем вам ставить "... вещи ..." между собственностью и полем? Я твердо верю в то, чтобы держать тесно связанные вещи как можно ближе:

class MyClass {
   ... stuff ...

  private string _myBackingField = "Foo";
  public string MyProperty {       
    get { return _myBackingField; }    
    set { _myBackingField = value; }
  }
}

Я бы также не вводил дополнительное поле, если бы мне не пришлось:

  • потому что мне нужна логика в аксессорах
  • по (BinaryFormatter) причинам сериализации

В приведенном примере я бы просто использовал автопроп:

class MyClass {
   ... stuff ...
  public MyClass() {
      MyProperty = "Foo";
  }
  [DefaultValue("Foo")]
  public string MyProperty { get;set; }
}

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

0 голосов
/ 09 ноября 2009

На практике это не имеет значения.

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

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

private string _Foo;
public string Foo 
{
    // arbitrarily complex get/set logic
}

Смысл ясен: _Foo используется только свойством Foo. Это значение не является надежным, хотя. Единственный способ убедиться, что в классе нет кода, который манипулирует _Foo, - это проверить его. Что ж, если я не могу полагаться на близость, чтобы сказать мне что-нибудь, зачем мне вообще заботиться о близости?

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

...