내가 이해 한 것처럼 귀하의 질문은 잘못된 전제에 기초한 것 같습니다. 추론을 재구성 할 수 있는지 살펴 보겠습니다.
- 링크 된 기사는 자동 생성 된 시퀀스가 "게으른"동작을 나타내는 방법을 설명하고 이것이 반 직관적 인 결과를 초래할 수있는 방법을 보여줍니다.
- 따라서 IEnumerable의 지정된 인스턴스가 자동으로 생성되는지 확인하여이 게으른 동작을 나타내는 지 여부를 감지 할 수 있습니다.
- 어떻게합니까?
문제는 두 번째 전제가 거짓이라는 것입니다. 주어진 IEnumerable이 반복자 블록 변환의 결과인지 여부를 감지 할 수 있다고하더라도 (예, 그렇게 할 수있는 방법이 있습니다) 가정이 잘못 되었기 때문에 도움이되지 않습니다. 이유를 설명해 봅시다.
class M { public int P { get; set; } }
class C
{
public static IEnumerable<M> S1()
{
for (int i = 0; i < 3; ++i)
yield return new M { P = i };
}
private static M[] ems = new M[]
{ new M { P = 0 }, new M { P = 1 }, new M { P = 2 } };
public static IEnumerable<M> S2()
{
for (int i = 0; i < 3; ++i)
yield return ems[i];
}
public static IEnumerable<M> S3()
{
return new M[]
{ new M { P = 0 }, new M { P = 1 }, new M { P = 2 } };
}
private class X : IEnumerable<M>
{
public IEnumerator<X> GetEnumerator()
{
return new XEnum();
}
// Omitted: non generic version
private class XEnum : IEnumerator<X>
{
int i = 0;
M current;
public bool MoveNext()
{
current = new M() { P = i; }
i += 1;
return true;
}
public M Current { get { return current; } }
// Omitted: other stuff.
}
}
public static IEnumerable<M> S4()
{
return new X();
}
public static void Add100(IEnumerable<M> items)
{
foreach(M item in items) item.P += 100;
}
}
네 가지 방법이 있습니다. S1 및 S2는 자동으로 생성 된 시퀀스입니다. S3 및 S4는 수동으로 생성 된 시퀀스입니다. 이제 우리가 가지고 있다고 가정 해보십시오.
var items = C.Sn(); // S1, S2, S3, S4
S.Add100(items);
Console.WriteLine(items.First().P);
S1 및 S4의 결과는 0입니다. 시퀀스를 열거 할 때마다 생성 된 M에 대한 새로운 참조가 제공됩니다. S2 및 S3의 결과는 100입니다. 시퀀스를 열거 할 때마다 마지막으로 얻은 M에 대한 동일한 참조가 나타납니다. 시퀀스 코드가 자동으로 생성되는지 여부는 열거 된 객체에 참조 ID가 있는지 여부와 직교합니다. 자동 생성과 참조 ID라는 두 가지 속성은 실제로 서로 관련이 없습니다. 당신이 연결 한 기사는 다소 혼란스러워합니다.
서열 제공자가 항상 참조 식별성 을 갖는 객체를 제공하는 것으로 문서화되지 않는 한 , 그렇게하는 것으로 가정하는 것은 현명하지 않습니다.
ICollection<T>
해야합니다List<T>
. 예를 들어, 배열은Point[]
구현IList<T>
하지만 그렇지 않습니다List<T>
.