Pertanyaan Anda, seperti yang saya mengerti, tampaknya didasarkan pada premis yang salah. Biarkan saya melihat apakah saya dapat merekonstruksi alasannya:
- Artikel yang ditautkan ke menjelaskan bagaimana urutan yang dibuat secara otomatis menunjukkan perilaku "malas", dan menunjukkan bagaimana ini dapat mengarah pada hasil kontra-intuitif.
- Oleh karena itu saya dapat mendeteksi apakah contoh IEnumerable yang diberikan akan menunjukkan perilaku malas ini dengan memeriksa untuk melihat apakah itu dihasilkan secara otomatis.
- Bagaimana aku melakukan itu?
Masalahnya adalah premis kedua salah. Bahkan jika Anda dapat mendeteksi apakah IEnumerable yang diberikan adalah hasil dari transformasi blok iterator (dan ya, ada cara untuk melakukan itu) tidak akan membantu karena anggapan tersebut salah. Mari kita ilustrasikan alasannya.
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;
}
}
Baiklah, kita punya empat metode. S1 dan S2 adalah urutan yang dihasilkan secara otomatis; S3 dan S4 adalah urutan yang dibuat secara manual. Sekarang misalkan kita memiliki:
var items = C.Sn(); // S1, S2, S3, S4
S.Add100(items);
Console.WriteLine(items.First().P);
Hasil untuk S1 dan S4 akan menjadi 0; setiap kali Anda menyebutkan urutannya, Anda mendapatkan referensi baru ke huruf M yang dibuat. Hasil untuk S2 dan S3 adalah 100; setiap kali Anda menyebutkan urutannya, Anda mendapatkan referensi yang sama dengan M yang Anda dapatkan terakhir kali.Apakah kode urutan dihasilkan secara otomatis atau tidak adalah ortogonal terhadap pertanyaan apakah objek yang disebutkan memiliki identitas referensial atau tidak. Dua properti itu - pembangkitan otomatis dan identitas referensial - sebenarnya tidak ada hubungannya satu sama lain. Artikel yang Anda tautkan agak mengkonfigurasinya.
Kecuali penyedia urutan didokumentasikan sebagai selalu menawarkan benda-benda yang memiliki identitas referensial , tidak bijaksana untuk berasumsi bahwa ia melakukannya.
ICollection<T>
akan menjadi pilihan yang lebih baik karena tidak semua koleksiList<T>
. Misalnya, arrayPoint[]
implementIList<T>
tetapi tidakList<T>
.