IEnumerable を返す次の 2 つのメソッドを検討してください。
private IEnumerable<MyClass> GetYieldResult(int qtResult)
{
for (int i = 0; i < qtResult; i++)
{
count++;
yield return new MyClass() { Id = i+1 };
}
}
private IEnumerable<MyClass> GetNonYieldResult(int qtResult)
{
var result = new List<MyClass>();
for (int i = 0; i < qtResult; i++)
{
count++;
result.Add(new MyClass() { Id = i + 1 });
}
return result;
}
このコードは、IEnumerable のメソッドを呼び出すときの 2 つの異なる動作を示しています。
[TestMethod]
public void Test1()
{
count = 0;
IEnumerable<MyClass> yieldResult = GetYieldResult(1);
var firstGet = yieldResult.First();
var secondGet = yieldResult.First();
Assert.AreEqual(1, firstGet.Id);
Assert.AreEqual(1, secondGet.Id);
Assert.AreEqual(2, count);//calling "First()" 2 times, yieldResult is created 2 times
Assert.AreNotSame(firstGet, secondGet);//and created different instances of each list item
}
[TestMethod]
public void Test2()
{
count = 0;
IEnumerable<MyClass> yieldResult = GetNonYieldResult(1);
var firstGet = yieldResult.First();
var secondGet = yieldResult.First();
Assert.AreEqual(1, firstGet.Id);
Assert.AreEqual(1, secondGet.Id);
Assert.AreEqual(1, count);//as expected, it creates only 1 result set
Assert.AreSame(firstGet, secondGet);//and calling "First()" several times will always return same instance of MyClass
}
コードが IEnumerables を返すときに必要な動作を選択するのは簡単ですが、「First()」メソッドを呼び出す回数に関係なく、単一の結果セットを作成するパラメーターとして一部のメソッドが IEnumerable を取得することを明示的に定義するにはどうすればよいでしょうか。
もちろん、すべての itens を不必要に強制的に作成したくはありません。また、パラメーターを IEnumerable として定義して、コレクションに含まれるアイテムやコレクションから削除されるアイテムがないことを示したいと考えています。
EDIT:明確にするために、問題はyieldがどのように機能するか、またはIEnumerableが呼び出しごとに異なるインスタンスを返す理由についてではありません。問題は、「First()」や「Take(1)」などのメソッドを数回呼び出したときに、パラメーターが MyClass の同じインスタンスを返す「検索のみ」のコレクションになるように指定するにはどうすればよいかということです。
何か案は?
前もって感謝します!