10

このように、関数でLINQクエリの結果を返すときに、かなりの数のエラーのケースにCollection was modified; enumeration operation may not execute遭遇しました...(インターフェイスの実装として機能する関数を追加する必要があり、結果はこのモジュールを使用するために残します別で。)

Public Function GetTheFuzzyFuzzbuzzes() As IEnumerable(of FuzzBuzz) _
    Implements IFoo.GetTheFuzzyFuzzBuzzes

    Return mySecretDataSource.Where(Function(x) x.IsFuzzy)
End Function

基になるデータが変更される可能性がある場合、原則として、.ToArrayLINQ クエリの結果を関数またはプロパティ getter で返すときに常に呼び出す必要がありますか? これを行うと効率が少し低下することはわかっていますが、安全に実行できると感じているため、一時的な結合の問題を回避するために常に実行する必要があります。

編集:

問題のドメインを説明するより良い仕事をさせてください。

最適化問題である主な関心領域のグラフベースの実装があります。エンティティはグラフ ノードとして表されます。さまざまなコストやその他のパラメーターで重み付けされたエッジは、ノード間の関係を表します。ユーザーがデータを操作すると、さまざまなエッジが作成され、現在の状態に対して実行できるさまざまなオプションが評価され、各オプションの結果に関するフィードバックが提供されます。他のユーザーやプログラムによってサーバー上のデータに加えられた変更は、プッシュ テクノロジを介して直ちにクライアントに伝達されます。私たちは多くのスレッドを使用しています...

...これはすべて、非常に非同期的な方法で多くのことが起こっていることを意味します。

私たちのプログラムは、(単一責任の原則に基づいて) 契約プロジェクトと実行時に解決される実装プロジェクトを含むモジュールに分割されています。つまり、インターフェイスに大きく依存しています。通常、IEnumerable を使用してモジュール間でデータを渡します (これらは一種の不変であるため)。

4

4 に答える 4

5

いいえ、私はこれについてルールを作りません。

私はあなたの懸念を理解しています。呼び出し側は、自分のアクションがクエリの結果に影響を与えることに気付いていない可能性があります。

実際にこれを行うことができないいくつかのケースがあります。

  • これを行うと、無限の列挙型や、反復ごとに新しく計算された画像を生成する列挙子など、メモリ不足が発生する例があります。(私は両方持っています)。
  • クエリでAny()またはを使用する場合。First()どちらも最初の要素を読み取るだけで済みます。他のすべての作業は無駄に行われます。
  • Enumerables がパイプ/フィルターでチェーンされることが予想される場合。中間結果の具体化は、追加コストのみです。

一方、多くの場合、配列を使用するとクエリに影響を与える副作用があると考えられる場合は、クエリを配列に実体化する方が安全です。

ソフトウェアを作成するとき、「X と Y のどちらかを選択する必要がある場合は、常に X を実行する」というルールがあると魅力的に聞こえます。そんなルールはないと思います。おそらく、15% の場合は X を実行する必要があり、5% の場合は Y を実行する必要があり、残りの場合は問題ありません。

残りの 80% の人にとっては、何もしないのが適切かもしれません。どこにでも挿入するToArray()と、コードは、これが行われた理由があったことを誤って示唆しています。

于 2012-07-19T17:53:29.727 に答える