คำถามของคุณที่ฉันเข้าใจดูเหมือนว่าจะขึ้นอยู่กับหลักฐานที่ไม่ถูกต้อง ให้ฉันดูว่าฉันสามารถสร้างเหตุผลใหม่ได้หรือไม่:
- บทความที่เชื่อมโยงไปยังอธิบายถึงวิธีที่ลำดับที่สร้างขึ้นโดยอัตโนมัติแสดงพฤติกรรม "ขี้เกียจ" และแสดงให้เห็นว่าสิ่งนี้สามารถนำไปสู่ผลลัพธ์ที่ตอบโต้ได้ง่ายหรือไม่
- ดังนั้นฉันสามารถตรวจสอบว่าอินสแตนซ์ที่กำหนดของ 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 ที่คุณได้รับครั้งล่าสุด ไม่ว่าจะเป็นรหัสลำดับที่ถูกสร้างขึ้นโดยอัตโนมัติหรือไม่เป็นคำถามที่ว่าวัตถุที่ระบุมีการอ้างอิงตัวตนหรือไม่ ทั้งสองคุณสมบัติ - การสร้างอัตโนมัติและตัวตนของการอ้างอิง - จริงๆแล้วไม่มีอะไรเกี่ยวข้องกัน บทความที่คุณเชื่อมโยงกับ conflates พวกเขาบ้าง
เว้นแต่ว่าผู้ให้บริการลำดับนั้นจะได้รับการบันทึกไว้เช่นเดียวกับการเสนอวัตถุที่มีข้อมูลประจำตัวอ้างอิงอยู่เสมอ
ICollection<T>
List<T>
ยกตัวอย่างเช่นอาร์เรย์Point[]
ดำเนินการแต่ไม่IList<T>
List<T>