myGrid.Rows
è di tipo DataGridViewRowCollection
.
Questa cosa è piuttosto vecchio, la sua definizione si legge:
public class DataGridViewRowCollection : ICollection, IEnumerable, IList
Hai visto le interfacce non generici? Questa classe potrebbe implementare IList<DataGridViewRow>
e quindi var
semplicemente funzionerebbe, ma è legacy.
IEnumerable
trasmette alcuna informazione circa il tipo di elemento, e la funzione di GetEnumerator
non aiuta qui, perché restituisce un IEnumerator
, mentre potrebbe restituire un IEnumerator<DataGridViewRow>
.
In sostanza, il compilatore C# cerca una funzione GetEnumerator
che restituisce un oggetto che ha una funzione e una proprietà MoveNext
Current
(o un'interfaccia IEnumerable<T>
/IEnumerable
una volta attuata in modo esplicito). Questo approccio duck-typing è per ragioni storiche, esisteva prima che i generici venissero introdotti nella lingua. La variabile di ciclo foreach
sarà dello stesso tipo della proprietà Current
. E all'interno di IEnumerator
(la variante non generica), Current
è di tipo object
.
Specificando il tipo in modo esplicito:
foreach (DataGridViewRow row in myGrid.Rows)
getta semplicemente il valore di ritorno di Current
ad un DataGridViewRow
, per mancanza di un meccanismo migliore.
Si potrebbe anche usare LINQ per ottenere lo stesso effetto, se si vuole veramente da usare che var
parola chiave qui:
foreach (var row in myGrid.Rows.Cast<DataGridViewRow>())
Questo funziona, perché il metodo di estensione Enumerable.Cast<T>
restituisce un IEnumerable<T>
, che a sua volta utilizza IEnumerator<T>
e T
come tipo della proprietà Current
dell'enumeratore, quindi le informazioni sul tipo vengono propagate.
Dubito che trarrai vantaggio da questi dettagli a questo punto, ma potresti voler tenerlo per ulteriore consultazione quando imparerai di più sulla lingua. Dovresti conoscere i metodi di estensione e i tipi generici per capire questo.
sembra che C# stia cercando di implicare il tipo sbagliato per DataGridViewRow, questo accade quando ci sono definizioni ambigue per myGrid.Rows – maximdumont
Avrai lo stesso problema con 'foreach (var row in dt.Rows)' dove 'dt 'è un' DataTable', ma specificando esplicitamente 'foreach (Riga DataRow in dt.Rows)' funziona bene – Habib