Wie ich es verstehe, scheint Ihre Frage auf einer falschen Prämisse zu beruhen. Lassen Sie mich sehen, ob ich die Argumentation rekonstruieren kann:
- Der verlinkte Artikel beschreibt, wie sich automatisch generierte Sequenzen "träge" verhalten und wie dies zu einem kontraintuitiven Ergebnis führen kann.
- Daher kann ich feststellen, ob eine bestimmte Instanz von IEnumerable dieses verzögerte Verhalten aufweisen wird, indem ich überprüfe, ob es automatisch generiert wird.
- Wie mache ich das?
Das Problem ist, dass die zweite Prämisse falsch ist. Selbst wenn Sie feststellen könnten, ob eine bestimmte IEnumerable das Ergebnis einer Iteratorblocktransformation ist (und ja, es gibt Möglichkeiten, dies zu tun), würde dies nicht helfen, da die Annahme falsch ist. Lassen Sie uns veranschaulichen, warum.
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;
}
}
Okay, wir haben vier Methoden. S1 und S2 sind automatisch generierte Sequenzen; S3 und S4 sind manuell erzeugte Sequenzen. Nehmen wir nun an, wir haben:
var items = C.Sn(); // S1, S2, S3, S4
S.Add100(items);
Console.WriteLine(items.First().P);
Das Ergebnis für S1 und S4 ist 0; Jedes Mal, wenn Sie die Sequenz aufzählen, erhalten Sie einen neuen Verweis auf ein erstelltes M. Das Ergebnis für S2 und S3 ist 100; Jedes Mal, wenn Sie die Sequenz aufzählen, erhalten Sie denselben Verweis auf M, den Sie beim letzten Mal erhalten haben. Ob der Sequenzcode automatisch generiert wird oder nicht, ist orthogonal zur Frage, ob die aufgezählten Objekte eine referenzielle Identität haben oder nicht. Diese beiden Eigenschaften - automatische Generierung und referenzielle Identität - haben eigentlich nichts miteinander zu tun. Der Artikel, den Sie verlinkt haben, widerspricht ihnen etwas.
Sofern ein Sequenzanbieter nicht dokumentiert ist, dass er Objekte mit referentieller Identität immer anbietet , ist es nicht ratsam , dies anzunehmen.
ICollection<T>
da dies nicht für alle Sammlungen der Fall istList<T>
. BeispielsweisePoint[]
implementieren Arrays diesIList<T>
jedoch nichtList<T>
.