Параметры инициализации объекта C # - PullRequest
5 голосов
/ 09 июля 2009

Разве объектная инициализация вне конструктора не нарушает инкапсуляцию?

Дано:

class MyClass 
{  
    public string _aString;  
}

Не должен ли член _aString быть закрытым и создаваться с помощью вызова конструктора (здесь конструктор не указан):

 MyClass test = new MyClass("test");

Вместо альтернативного метода инициализации объекта:

MyClass test = new MyClass { _aString = "Test" };

Ответы [ 8 ]

6 голосов
/ 09 июля 2009

"Разве объектная инициализация вне конструктора не нарушает инкапсуляцию?"

Ну нет. Как вы правильно заметили, вы можете только инициализировать свойства, которые уже доступны в вашей текущей области. (общедоступный, внутренний и т. д.)

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

5 голосов
/ 09 июля 2009

Обычно считается плохой практикой выставлять открытые поля ... это может быть приемлемо в некоторых случаях, например, если поле помечено как readonly (что означает, что оно должно быть установлено в конструкторе). Вместо этого вы должны сделать это поле закрытым и открыть его через свойство, которое может быть или не быть доступно только для чтения, в зависимости от его назначения:

class MyClass
{
    private string _aString;
    public string AString
    {
        get { return _aString; }
        // uncomment to make the property writable
        //set { _aString = value; }
    }
}
1 голос
/ 09 июля 2009

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

class MyClass {
    private string aString;

    public string AString {
        get { return aString; }
        set {aString = value; }
    }
}
MyClass test = new MyClass {
    AString = "test"
};

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

0 голосов
/ 09 июля 2009

Показ объекта public в классе C # не нарушает «инкапсуляцию» с точки зрения «объектно-ориентированного программирования».

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

0 голосов
/ 09 июля 2009

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

MyClass test = new MyClass { _aString = "Test" };

совпадает с

MyClass test = new MyClass();
test._aString = "Test";
0 голосов
/ 09 июля 2009

да, инициализируйте через конструктор и добавьте свойства, чтобы разрешить (или нет) доступ к данным.

class MyClass {
private string _aString;
string MyProperty {
                    get { return this._aString; }
                    // you can make this  private or protected
                    set { this._aString = value; } 

                  }
}
0 голосов
/ 09 июля 2009

Когда у вас есть
public string _aString;
это действительно не имеет значения, когда вы инициализируете это значение, так как оно уже выставлено. Итак, когда мы хотим поговорить об инициализации, мы должны переместить эту строку в свойство. Чем разговор о инкапсуляции имеет смысл.
Итак, представьте, у нас есть какая-то строка. Есть два подхода к инициализации. Один - сделать это внутри конструктора, второй - ленивая инициализация (инициализация, когда некоторые запрашивают эти данные).

0 голосов
/ 09 июля 2009

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

...