1

I assumed it's of type Match, but that's not correct because I'm getting the error

Cannot implicitely convert type type 'System.Collections.IEnumerator' to type 'System.Collections.Generic.IEnumerator

on the line

IEnumerator<Match> friendsULsEnumerator = friendsULs.GetEnumerator();

where friendsULs is of type MatchCollection. I tried doing

var friendsULsEnumerator = friendsULs.GetEnumerator();

and hovering over the var to see if Visual Studio told me the specific type, but it only showed IEnumerable. :(

To broaden my question to my greater problem, I'm trying to get the values Donald Trump, Hillary Clinton, etc. out of a string

<h2>Friends</h2><ul><li>Donald Trump</li><li>Hillary Clinton</li>...</ul>

which occurs only once in a larger string. So what I have is

                MatchCollection friendsULs = DataReader._fregx.Matches(sr.ReadToEnd());
                if ( friendsULs.Count != 1 ) throw new Exception(String.Format("Couldn't find exactly one piece of HTML matching {0}", 
                                                                                DataReader._fregx.ToString()));
                IEnumerator<Match> friendsULsEnumerator = friendsULs.GetEnumerator();
                if ( friendsULsEnumerator.MoveNext() )  { } // because MoveNext() returns a bool, this useless block is necessary
                MatchCollection friendsLIs = DataReader._lregx.Matches(friendsULsEnumerator.Current.ToString()); 

but maybe you can suggest a more compact and elegant way of doing that entirely.

  • https://msdn.microsoft.com/en-us/library/system.text.regularexpressions.matchcollection(v=vs.110).aspx for matchcollectoin (it has example in the bottom). Where are you getting this html from and is it xhtml ? Check this question(http://stackoverflow.com/questions/56107/what-is-the-best-way-to-parse-html-in-c) and obvious answer - HTML Agility Pack – vittore Nov 08 '15 at 18:51
  • @vittore The example on that page does not answer my question – Abolish the IRS Nov 08 '15 at 18:53
  • Perhaps this one will shed some light http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 – Steve Nov 08 '15 at 18:56
  • @Steve In my situation the format of the HTML of the files I'm reading is consistent enought for me to employ regular expression searches without any potential problems – Abolish the IRS Nov 08 '15 at 18:58

3 Answers3

2

The method you're calling, GetEnumerator is a method defined by the non-generic IEnumerable interface. It returns a non-generic IEnumerator, which is not the same as the IEnumerator<T>. So to answer your question: MatchCollection is indeed a collection of Match objects, but as it does not implement the generic IEnumerable<Match> interface, you need to "cast" manually. The OfType method does exactly this: converting a non-generic IEnumerable collection to a generic one of the type specified.

That said, GetEnumerator is a method you would seldomly need in "canonical C#". From your code example, it seems that you just need to get the first Match in the collection. This is much easier and more elegant with LINQ, for example with the Single operator:

Match match = friendsULs.OfType<Match>().Single();
jeroenh
  • 26,362
  • 10
  • 73
  • 104
1

You can easily iterate over the matches using:

foreach(Match match in friendsULs)
   // do whatever with match here

This is the NET 1.0 pattern of iterating enumerables, since there were no generics back then.

Blindy
  • 65,249
  • 10
  • 91
  • 131
0

The underlying type of a MatchCollection is indeed a Match. GetEnumerator() returns a simple IEnumerator (i.e. the version pre-dating generics, where all the elements are an object and you need to cast them yourself.)

Typically you would process all the items in a loop like this:

for (int i = 0; i < friendULs.Count; i++)
{
    Match thisMatch = friendULs[i];
    ...
}

You can convert a MatchCollection to an IEnumerable<Match> with friendsULs.OfType<Match>().

Matthew Strawbridge
  • 19,940
  • 10
  • 72
  • 93