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

// I'd like totalEstimatedUse to be the total of estimatedType1 + estimatedType2
public class EstimatedUse
{
    public string ID { get; set; }
    public double estimatedType1 { get; set; }
    public double estimatedType2 { get; set; }
    public double totalEstimatedUse { get; set; } // I'd like this to be the sum
}

    // parameterless constructor - I cannot get anything to work inside this because
    // 'this' has no values when it's populated (from linq in my code)
    public EstimatedUse
    {
    }

    // here is a constructor that has parameters
    public EstimatedUse(string id, double estimatedType1, double estimatedType2)
    {
        this.ID = id;
        this.estimatedType1 = estimatedType1;
        this.estimatedType2 = estimatedType2;
        this.totalEstimatedUse = estimatedType1 + estimatedType2;
    }

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

EstimatedUse estimatedUse = null;

// cutoff linq to keep example clean
.Select(e => new EstimatedUse
{
    ID = e.ProjectID,
    estimatedType1 = e.estimatedType1),
    estimatedType1 = e.estimatedType2),
}).FirstOrDefault();

// below is to set the length but I wish I could set in the parameterless constuctor if    
// it's possible    
estimatedUse = new EstimatedUse(estimatedUse.ID, estimatedUse.estimatedType1,
                                stimatedUse.estimatedType2);
0
chuck 13 Авг 2014 в 23:22
3
Почему бы просто не вызвать конструктор (3 аргумента) внутри метода .Select?
 – 
Andrew Whitaker
13 Авг 2014 в 23:25

5 ответов

Лучший ответ

Возможно, вам будет удобнее изменить свойство totalEstimatedUse на свойство только для чтения, которое автоматически суммирует значения.

public class EstimatedUse
{
    public string ID { get; set; }
    public double estimatedType1 { get; set; }
    public double estimatedType2 { get; set; }

    public double totalEstimatedUse
    {
        get { return this.estimatedType1 + this.estimatedType2; }
    }

    // ...
}

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

2
Adam Maras 13 Авг 2014 в 23:26

Вы также можете просто изменить геттер свойства totalEstimatedUse, чтобы автоматически вычислять сумму при доступе к нему:

public class EstimatedUse
{
    public string ID { get; set; }
    public double estimatedType1 { get; set; }
    public double estimatedType2 { get; set; }
    public double totalEstimatedUse { get { return estimatedType1 + estimatedType2; }
}
1
mclaassen 13 Авг 2014 в 23:26
Это то, что мне нужно было сделать. Автоматический расчет значений полезен.
 – 
chuck
13 Авг 2014 в 23:42

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

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

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

0
Servy 13 Авг 2014 в 23:24

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

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

0
SonalKhodiyar 13 Авг 2014 в 23:27

Просто удалите конструктор без параметров и используйте конструктор с параметрами:

.Select(e => new EstimatedUse(e.ProjectID,e.estimatedType1e.estimatedType2))
.FirstOrDefault();

Нет причин использовать инициализатор объекта, если у вас есть лучший вариант конструктора.

0
Reed Copsey 13 Авг 2014 в 23:30