C # предварительно инициализированный класс - PullRequest
2 голосов
/ 09 августа 2011

Какая лучшая практика для создания предварительно инициализированного класса. Например

Chip chip = new Atmega8();

Я бы хотел, чтобы его свойства уже были определены как:

chip.Name = "Atmega8 AVR Chip";

и т. Д.

Как этого добиться в C #?
Должен ли я использовать readonly public свойства или свойство с private set?

Ответы [ 7 ]

4 голосов
/ 09 августа 2011

Пусть ваш конструктор инициализирует значения:

class Atmega8 {
    public Atmega8 ()
    {  
        Name = "Atmega8 AVR Chip";
    }

    public string Name { get; set; }
}

Если вы хотите, чтобы Name было одинаковым для всех экземпляров, возможно, имеет смысл объявить его abstract в базовом классе и переопределить метод получения:

abstract class Chip {
    public abstract string Name { get; }
}

class Atmega8 : Chip {
    public override string Name {
        get { return "Atmega8 AVR Chip"; }
    }
}

Поскольку мы не определили метод set, значение не может быть изменено, как и переменная readonly, за исключением того, что она даже нигде не сохраняется и просто возвращается при каждом вызове.

3 голосов
/ 09 августа 2011

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

Если вы абсолютно безразлично НЕ ХОТИТЕ изменить значение для определенного класса, НИКОГДА, тогда я бы сделал его доступным только для свойства, возвращая либо строковый литерал, либо константу. Я бы порекомендовал использовать константу над литералом, поскольку вы можете поместить константы в их собственный статический класс, который затем можно использовать отдельно от каждого класса Chip.

ОДНАКО, есть причуды констант, которые вы должны знать. Постоянное значение в .NET хранится в манифесте не только сборки, содержащей декларирующий код, но и в каждой сборке, которая ссылается на декларирующую сборку. Каждый код каждой сборки использует значение из своего собственного манифеста. Таким образом, если постоянное значение EVER изменяется, любая сборка, которая ссылается на декларируемую сборку, должна быть перекомпилирована для обновления манифестов этих сборок новым значением. В противном случае константа будет иметь свое новое значение только при использовании из декларирующей сборки. По этой причине маркировка переменной как константы не должна выполняться легко. Лично я считаю, что если константа не является какой-то ценностью, от которой зависит непрерывное существование и функционирование вселенной, например, пи, е, скорость света в вакууме, постоянная Планка, число Авогадро и т. Д., То это не так. т "постоянная". Все остальное, например, порядковые номера кода связи, МОЖЕТ измениться, даже если это нарушит совместимость со всеми предыдущими версиями вашей программы.

1 голос
/ 09 августа 2011

В конструкторе класса Atmega8 вы можете установить свойство для чего-либо. То есть:

public Atmega8() {
    Name = "Atmega8 AVR Chip";
}

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

private readonly string _Name = string.Empty;

public string Name {
    get { return _name; }
}

public Atmega8() {
    _Name = "Atmega8 AVR Chip";
}
1 голос
/ 09 августа 2011

Зависит от того, что вы хотите достичь.

Похоже, вы никогда не хотите, чтобы значение Name изменилось.Одним из подходов было бы объявить Name как abstract в Chip и внедрить Name в каждом дочернем классе, чтобы получить постоянное строковое значение.

abstract class Chip
{
    public abstract string Name { get; }
}

class Amiga8 : Chip
{
    public override string Name { get { return "Atmega8 AVR Chip"; } }
}

class Program
{

    static void Main(string[] args)
    {
        Chip chip = new Amiga8();
        Console.WriteLine(chip.Name);
    }
}
0 голосов
/ 09 августа 2011

Вы говорите, что хотите, чтобы класс заполнялся одновременно с инициализацией?Просто заполните объект в конструкторе, вот так:

class Test
{
    public Test()
    {
        this.Name = "Hello World";
    }

    //if you need to pass information into the constructor:
    public Test(string testName)
    {
        this.Name = testName;
    }
}

Затем вы можете сделать это для его инициализации:

Test test = new Test(); //default name of Hello World!

ИЛИ

Test test = new Test("Bingo!");
0 голосов
/ 09 августа 2011

Если вы не хотите, чтобы оно изменялось, сделайте свойство Name постоянным или доступным только для чтения в классе Atmega8. Частный набор все еще позволяет Имени измениться внутренне.

0 голосов
/ 09 августа 2011

Значение свойства не может измениться -> Публичное свойство только для чтения.

Стоимость недвижимости может меняться -> Недвижимость с private set

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...