Проблема с заполнением объекта списка при попытке сравнить 2 объекта списка

#c#

#c#

Вопрос:

Я пытаюсь сравнить данные 2 подвариантов одновременно, а затем на основе этого подготовить результаты следующим образом :

 Subvariants[0]  -   Subvariants[1]

Subvariants[1]  -   Subvariants[2]
.
.
so on 
  

Допустим, ниже приведен результат сравнения приведенного выше подвариантного списка :

 Subvariants[0]  -   Subvariants[1] = Success

Subvariants[1]  -   Subvariants[2] = Error
  

Теперь, после обработки Subvariants[0] - Subvariants[1] is success so, я хочу заполнить свой AggregateResults with 2 records (Subvariants [0],Subvariants [1]), но у Subvariants[1] — Subvariants[2] ошибка, поэтому я хочу заполнить свои AggregateResults только 1 записью, содержащей Name and ErrorMessage информацию о подвариантах [2] со значением свойства Success false.

Но здесь проблема в том, как мне получить совокупные результаты для подвариантов в разделе catch, в котором есть ошибка?

Код :

 public class Aggregate
{
    public string Name { get; internal set; }
    public string ErrorMessage { get; internal set; }
    public bool Success { get; internal set; } = true;
    //other properties
}

public class ExecutionResult
{
    public string VariantName { get; set; }
    public IEnumerable<AggregateStats> AggregateResults { get; set; }
}

public class Variant
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Subvariants> Subvariants { get; set; }
}

public class Subvariants
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public ExecutionResult GetExecutionResult(Variant model)
    {
        var executionResult = new ExecutionResult();
        executionResult.Name = model.VariantName;
        var aggregateResults = new List<AggregateStats>();
        try
        {
            for (int counter = 0; counter < model.Subvariants.Count - 1; counter  )
            {
                var left = model.Subvariants[counter];
                var right = model.Subvariants[counter   1];
                using (var t = new AggregateCalculator(model))
                {
                    for (int i = 0; i < 2; i  )
                    {
                        if (i == 0)
                        {
                            t.Start(i);
                            if (counter == 0)
                            {
                                aggregateResults.Add(new AggregateStats
                                {
                                    Name = left.Name,
                                    //other properties
                                });
                            }
                        }
                        else
                        {
                            t.Start(i);
                            aggregateResults.Add(new AggregateStats
                            {
                                Name = right.Name,
                                //other properties
                            });
                        }
                    }
                }
            }
            aggregateResults.AggregateResults = aggregateResults.AsReadOnly();
        }
        catch (Exception ex)
        {
        }
        return executionResu<
    }
  

Ответ №1:

@Matti Price прав насчет try-catch местоположения. При этом есть другой вариант: использование перечислителя. Это, на мой взгляд, легче читать и поддерживать. Это также гарантирует, что код не дублируется (я создал методы для разделения дублированного кода и передачи параметров вместо этого). Кроме того, вам не нужен List для отслеживания ваших результатов.

 public ExecutionResult GetExecutionResult(Variant model)
{
    return new ExecutionResult
    {
        Name = model.VariantName,
        AggregateResults = CaclulateAggregates(model);
    };
}

private IEnumerable<AggregateStats> CaclulateAggregates(Variant model)
{
    for (int counter = 0; counter < model.Subvariants.Count - 1; counter  )
    {
        try
        {
            var left = model.Subvariants[counter];
            var right = model.Subvariants[counter   1];

            using (var t = new AggregateCalculator(model))
            {
                if (counter == 0)
                {
                    t.Start(0);
                    yield return CreateStats(left.Name);
                }

                t.Start(1);
                yield return CreateStats(left.Name);
            }
        }
        catch
        {
            yield return CreateStats(left.Name);
            yield break;
        }
    }
}

private AggregateStats CreateStats(string name)
{
    return new AggregateStats
    {
        Name = name,
        //other properties (add parameters)
    }
}
  

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

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

Ответ №2:

Вам нужно переместить ваш блок try-catch внутри вашего for цикла, чтобы он имел контекст счетчика и мог получить доступ / вычислить данные, которые вам нужно назначить в вашем объекте error. Что-то вроде этого:

 public ExecutionResult GetExecutionResult(Variant model) {
            var executionResult = new ExecutionResult();
            executionResult.Name = model.VariantName;
            var aggregateResults = new List<AggregateStats>();

            for(int counter = 0; counter < model.Subvariants.Count - 1; counter  ) {
                var left = model.Subvariants[counter];
                var right = model.Subvariants[counter   1];
                try {
                    using(var t = new AggregateCalculator(model)) {
                        for(int i = 0; i < 2; i  ) {
                            if(i == 0) {
                                t.Start(i);
                                if(counter == 0) {
                                    aggregateResults.Add(new AggregateStats {
                                        Name = left.Name,
                                        //other properties
                                    });
                                }
                            }
                            else {
                                t.Start(i);
                                aggregateResults.Add(new AggregateStats {
                                    Name = right.Name,
                                    //other properties
                                });
                            }
                        }
                    }
                }
                catch(Exception ex) {
                    aggregateResults.Add(new AggregateStats {
                        Name = left.Name,
                        //other error props
                    });
                    //breaks out of for loop, preventing continuation
                    break;
                }
            }
            //changed this because I think this is what you meant, previously it didn't make any sense since you weren't assigning anything to executionResult
            executionResult.AggregateResults = aggregateResults.AsReadOnly();


            return executionResu<
        }
  

Комментарии:

1. Проблема в том, что если я получаю ошибку в своих подвариантах [0], то все равно это продолжается, чего я не хочу. Если в первой записи есть ошибка, то она не должна продвигаться вперед

2. Я не уверен, что понимаю. Вы хотите, чтобы он полностью прерывался при возникновении ошибки и возвращал результаты с точностью до этой ошибки, а не продолжался дальше? Это правильно?

3. Да, правильно. Когда возникает ошибка, я не хочу продолжать

4. Обновлено, это должно сработать.