La tua domanda, a quanto ho capito, sembra basata su una premessa errata. Fammi vedere se riesco a ricostruire il ragionamento:
- L'articolo linkato descrive come le sequenze generate automaticamente mostrano un comportamento "pigro" e mostra come ciò possa portare a un risultato contro-intuitivo.
- Quindi posso rilevare se una determinata istanza di IEnumerable mostra questo comportamento pigro controllando per vedere se viene generata automaticamente.
- Come faccio?
Il problema è che la seconda premessa è falsa. Anche se si potesse rilevare se un dato oggetto IEnumerable fosse o meno il risultato di una trasformazione del blocco iteratore (e sì, ci sono modi per farlo) non sarebbe d'aiuto in quanto l'assunto è sbagliato. Illustriamo il motivo.
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;
}
}
Va bene, abbiamo quattro metodi. S1 e S2 sono sequenze generate automaticamente; S3 e S4 sono sequenze generate manualmente. Ora supponiamo di avere:
var items = C.Sn(); // S1, S2, S3, S4
S.Add100(items);
Console.WriteLine(items.First().P);
Il risultato per S1 e S4 sarà 0; ogni volta che si enumera la sequenza, si ottiene un nuovo riferimento a una M creata. Il risultato per S2 e S3 sarà 100; ogni volta che si enumera la sequenza, si ottiene lo stesso riferimento a M ottenuto l'ultima volta. Se il codice di sequenza viene generato automaticamente o meno è ortogonale alla domanda se gli oggetti enumerati abbiano o meno un'identità referenziale. Queste due proprietà - generazione automatica e identità referenziale - in realtà non hanno nulla a che fare con l'un l'altro. L'articolo che hai collegato li confonde un po '.
A meno che un fornitore di sequenze non sia documentato come offrire gli oggetti con identità referenziale , non è saggio presumere che lo faccia.