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 に答える