Должен ли я реализовать конструктор или использовать конструктор по умолчанию для классов данных? - PullRequest
1 голос
/ 28 октября 2009

Класс данных в этом вопросе является классом с более открытыми свойствами, чем методы.

Должен ли я:

public class Complex
{
    public double Real { get; set; }
    public double Imaginary { get; set; }
}

Или:

public class Complex
{
    public double Real { get; set; }
    public double Imaginary { get; set; }
    public Complex(double real, double imaginary)
    {
        this.Real = real;
        this.Imaginary = imaginary;
    }
}

Ответы [ 7 ]

3 голосов
/ 28 октября 2009

В вашем примере, комплексное число, я бы сделал его неизменным struct вместо:

public struct Complex
{
    private readonly double _real;
    public double Real
    {
        get { return _real; }
    }

    private readonly double _imaginary;
    public double Imaginary
    {
        get { return _imaginary; }
    }

    public Complex(double real, double imaginary)
    {
        _real = real;
        _imaginary = imaginary;
    }
}

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

3 голосов
/ 28 октября 2009

Я думаю, что это действительно зависит от того, нужны ли вам эти значения для инициализации. Вы не можете зависеть от действительных и мнимых значений, установленных без явного принуждения их устанавливать в конструкторе. Технически, кто-то может установить им какое-то произвольное значение в конструкторе, что может вызвать проблемы, но, принудительно устанавливая их в конструкторе, вы, по сути, говорите: «Эй! Эти значения важны для объекта».

3 голосов
/ 28 октября 2009

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

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

var c = new Complex { Imaginary = 1, Real = 2 };

Здесь вы можете найти пример использования инициализации «нового» объекта: http://www.developer.com/net/csharp/article.php/3605011/One-Step-Object-Creation-and-Initialization-in-C-30.htm

1 голос
/ 28 октября 2009

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

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

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

0 голосов
/ 30 октября 2009

Согласитесь с Кевином - это зависит. В сценарии 1 ваш дизайн говорит: «Вы можете изменить эти значения так, как вы хотите», в сценарии 2 - «вы должны дать мне некоторые значения с самого начала». В сценарии 2 я, скорее всего, изменил бы дизайн на что-то вроде этого, иначе конструктор ничего вам не купит:

public class Complex
{
    public double Real { get; private set; }
    public double Imaginary { get; private set; }
    public Complex(double real, double imaginary)
    {
        this.Real = real;
        this.Imaginary = imaginary;
    }
}
0 голосов
/ 28 октября 2009

Оба. Или это зависит.

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

  1. Complex c = new Complex { Real = 1d, Imaginary = 0.5 };
  2. Complex c = new Complex(1d, 0.5d);

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

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

Лично я склонен создавать свои объекты передачи данных (которые вряд ли являются объектами) с пустыми конструкторами, чтобы упростить сериализацию, а также удобные конструкторы, которые я использую во всем коде. Для моих объектов значений я использую только явные конструкторы с обязательными свойствами, чтобы обеспечить правильное состояние.

0 голосов
/ 28 октября 2009

Ну, в случае комплексного числа, я бы сказал, что оно должно быть неизменным struct, а не class с сеттерами. Поэтому ему нужно будет инициализировать свои значения в конструкторе.

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

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