2009-11-19 5 views
3

Je ne comprends pas pourquoi var m ne retourne pas Match. Je n'ai pas vérifié mais il semble retourner un objet.différence var et Type. Pourquoi doesnt travail Var ici?

 foreach (var m in Regex.Matches("dummy text", "(mm)")) 
      var sz = m.Groups[1]; // error CS1061: 'object' does not contain a definition for 'Groups' and no extension method 'Groups' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?) 

     foreach (Match m in Regex.Matches("dummy text", "(mm)")) 
      var sz = m.Groups[1]; //ok 

Répondre

9

MatchCollection met en œuvre IEnumerable plutôt que IEnumerable<Match> donc le compilateur ne peut déduire le type de la variable object plutôt que Match.

+0

Vous gagnez pour expliquer tout ce que je voulais savoir quand le moins de mots. –

+0

et je pense que cette réponse est complète. –

+0

Merci, content d'avoir laissé ma réponse courte et douce! – RTPeat

11

Regex.Matches retours MatchCollection qui met en oeuvre IEnumerable et non IEnumerable<Match>.

Par conséquent, le type d'élément par défaut est objet. Lorsque vous utilisez le type d'élément Match dans le foreach vous obtenez le type d'élément attendu.

+0

Vous voulez dire "retourne" au lieu de "implémente". –

+0

Merci Stefan, j'ai raté le type de retour en réponse :) – Elisha

7

varinfère le type de la variable à compilent le temps du type de l'expression, il est initialisé à. Matches renvoie MatchCollection qui implémente la vieille école IEnumerable et non le IEnumerable<Match> générique. Le type de la propriété Current renvoyée par l'énumérateur de IEnumerable.GetEnumerator() est object. Ainsi, var va déduire le type de m pour être object et non Match.

Lorsque vous spécifiez explicitement le type dans une instruction foreach et que le type de retour de l'énumérateur diffère, le compilateur insère silencieusement une instruction cast pour effectuer ce travail. Aucune autre vérification de temps de compilation ne peut être effectuée dans ce cas et il lancera un InvalidCastException lors de l'exécution en cas d'échec.