尝试比较2个列表对象时填充列表对象的问题

时间:2019-03-13 13:02:15

标签: 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,所以我想填充我的AggregateResults with 2 records Subvariants [0],Subvariants [1] ),但要填充Subvariants [1]-Subvariants [2]发生错误,因此我只用1条包含Subvariants [2] Name and ErrorMessage信息且Success属性值为false的记录填充我的AggregateResults。

但是这里的问题是我如何捕获具有错误的catch部分中的Subvariant的AggregateResults?

代码:

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 executionResult;
    }

2 个答案:

答案 0 :(得分:3)

@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(),这将计算整个枚举并使用它创建一个数组。

答案 1 :(得分:2)

您需要在for循环内移动try-catch块,以使其具有计数器上下文,并可以访问/设计出需要在错误对象中分配的数据。像这样:

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 executionResult;
        }