次のようなステートメントがあった場合:
var item = Core.Collections.Items.FirstOrDefault(itm => itm.UserID == bytereader.readInt());
このコードは、反復ごとにストリームから整数を読み取りますか? それとも、整数を 1 回読み取って格納し、ルックアップ全体でその値を使用しますか?
次のコードを検討してください。
static void Main(string[] args)
{
new[] { 1, 2, 3, 4 }.FirstOrDefault(j => j == Get());
Console.ReadLine();
}
static int i = 5;
static int Get()
{
Console.WriteLine("GET:" + i);
return i--;
}
条件に一致する最初の要素を満たすために必要な回数だけメソッドを呼び出すことを示しています。出力は次のようになります。
GET:5
GET:4
GET:3
チェックしないとわかりませんが、毎回読んでくれると思います。
ただし、これは次のバージョンのコードで非常に簡単に改善されます。
byte val = bytereader.readInt();
var item = Core.Collections.Items.FirstOrDefault(itm => itm.UserID == val);
私自身、疑いを取り除くためだけに、とにかくこのアプローチを自動的に採用します。項目ごとに読む必要がないので、良い習慣になるかもしれません。
呼び出しがアイテムごとに実行されることは、実際には非常に明白ですFirstOrDefault()
。デリゲートを引数として取ります。この事実は、ラムダ メソッドを使用することで少しわかりにくくなりますが、最終的にメソッドは、述語をチェックするために各項目に対して呼び出すことができるデリゲートのみを認識します。右辺を 1 回だけ評価するには、いくつかの魔法のメカニズムがメソッドを理解して書き直す必要があり、(悲しいことに) コンパイラとランタイム内に本当の魔法はありません。