2009-05-28 4 views
1

Можно создать дубликат:
C# member variable initialization; best practice?Каковы наилучшие методы для создания и инициализации частных пользователей?

Есть ли польза для этого:

public class RemotingEngine 
{ 
    uint m_currentValueId; 
    object m_lock; 

    public RemotingEngine() 
    { 
     m_currentValueId = 0; 
     m_lock = new object(); 
    } 

против этого:

public class RemotingEngine 
{ 
    uint m_currentValueId = 0; 
    object m_lock = new object(); 

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

+2

точная копия http://stackoverflow.com/questions/298183/c-member-variable-initialization-best-practice – Robert

+0

К сожалению, я не видел, что один в списке подобных тем. –

ответ

7

Это может сделать разницу в качестве ситуации наследования.Смотрите эту ссылку на порядке инициализации объекта:
http://www.csharp411.com/c-object-initialization/

  1. Походных статических поля
  2. производных статический конструктор
  3. производного полей экземпляра
  4. Базовых статические поля
  5. Базовых статический конструктор
  6. базового экземпляра поля
  7. Конструктор базового экземпляра
  8. производного конструктор экземпляра

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

0

Они идентичны по сравнению с ИЛ.

Компилятор превращает это:

class Foo 
{ 
    int bar = 1; 
} 

в этом:

class Foo 
{ 
    int bar; 

    public Foo() 
    { 
     this.bar = 1; 
    } 
} 

Даже если добавить конструктор себя так:

class Foo 
{ 
    int bar = 1; 

    public Foo(int bar) 
    { 
     this.bar = bar; 
    } 
} 

компилятор превращает его в это:

class Foo 
{ 
    int bar; 

    public Foo(int bar) 
    { 
     this.bar = 1; 
     this.bar = bar; 
    } 
} 
+0

до добавления другого конструктора –

+0

@Neil N: Пожалуйста, объясните больше - ваше утверждение не имеет никакого смысла. –

+0

В некоторых случаях (когда вы получили) ИЛ определенно НЕ то же самое. –

1

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

1

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

0

Для междунар, вы не должны делать это вообще, внутренние типы инициализируются по умолчанию() - который, для INT равно 0.

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

0

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

1

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

целевой инициализации полей классов -> Инициализация поля базового класса -> базовый конструктор класса -> целевой конструктор класса

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

Смотрите также этот блог Билл Simser Best Practices and Member Initialization in C#

0

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

public class RemotingEngine { 
    private uint CurrentValueID { get; set; } 
    private object Lock { get; set; } 

    public RemotingEngine() 
    { 
     this.CurrentValueID = 0; // not really necessary... 
     this.Lock = new object(); 
    } 
} 
+0

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

Смежные вопросы