0

我有以下 c# 代码:

    private XElement BuildXmlBlob(string id, Part part, out int counter)
    {
        // return some unique xml particular to the parameters passed
        // remember to increment the counter also before returning.
    }

由以下人员调用:

        var counter = 0;
        result.AddRange(from rec in listOfRecordings
                        from par in rec.Parts
                        let id = GetId("mods", rec.CKey + par.UniqueId)
                        select BuildXmlBlob(id, par, counter));

上面的代码示例象征着我想要实现的目标。

根据 Eric Lippert 的说法,out 关键字和 linq 不能混合使用。好吧,很公平,但是有人可以帮我重构上面的内容,让它起作用吗?工作中的一位同事提到了累加器和聚合函数,但我是 Linq 的新手,而且我的谷歌搜索结果有任何真正的成果,所以我想我会在这里问:)。

澄清:

我正在计算每次调用代码时我可能拥有的部件数量,这些部件数量可能是任意数量。因此,每次调用 BuildXmlBlob() 方法时,生成的 xml 都会有一个唯一元素,表示“partNumber”。

因此,如果计数器当前位于 7,这意味着我们目前正在处理第 7 部分!这意味着从 BuildXmlBlob() 返回的 XML 将在某处嵌入计数器值。这就是为什么每次运行时每次调用 BuildXmlBlob() 时我都需要以某种方式传递和递增它。

4

2 回答 2

1

如果您想纯粹在 LINQ 中保留它,并且需要维护一个运行计数以在查询中使用,那么最干净的方法是利用Select()查询中包含索引的重载来获取当前索引。

在这种情况下,先做一个收集输入的查询,然后使用重载进行投影会更干净。

var inputs =
    from recording in listOfRecordings
    from part in recording.Parts
    select new
    {
        Id = GetId("mods", recording.CKey + part.UniqueId),
        Part = part,
    };
result.AddRange(inputs.Select((x, i) => BuildXmlBlob(x.Id, x.Part, i)));

那么你就不需要使用out/ref参数了。

XElement BuildXmlBlob(string id, Part part, int counter)
{
    // implementation
}
于 2013-02-05T16:55:33.557 回答
0

以下是我自己设法弄清楚的:

            result.AddRange(listOfRecordings.SelectMany(rec => rec.Parts, (rec, par) => new {rec, par})
                            .Select(@t => new
                                {
                                    @t, 
                                    Id = GetStructMapItemId("mods", @t.rec.CKey + @t.par.UniqueId)
                                })
                            .Select((@t, i) => BuildPartsDmdSec(@t.Id, @t.@t.par, i)));

我使用 resharper 将其转换为一个方法链,该方法链构建了我需要的基础知识,然后我只是在最后添加了 select 语句。

于 2013-02-05T17:04:07.763 回答