Using LINQ with classes implementing non-generic I

2019-04-20 11:04发布

I wanted to run a LINQ query against a MatchCollection object but found this wasn't possible as it doesn't implement ICollection<T>, just ICollection.

What is the best option for using LINQ with non-generic collections, both in terms of code conciseness but also performance and memory usage?

(If interested, here is the non-LINQuified code:)

MatchCollection fieldValues = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)");
foreach (Match m in fieldValues)
{
    if (m.Groups["text"].Value.Equals(someString))
    {
        // Do stuff
    }
}

2条回答
我命由我不由天
2楼-- · 2019-04-20 12:03

Try to use the Cast extension method which will return an IEnumerable.

IEnumerable<Match> query = from Match m in fieldValues.Cast<Match>()
                           select m;

And event if you don't use the Cast method the compiler will infer the type of "query" to IEnumerable.

  var query = from Match v in fieldValues
                        select v;
查看更多
Lonely孤独者°
3楼-- · 2019-04-20 12:07

You can include your someString filter with LINQ as well.

var matches = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)");
var textMatches = from Match m in matches
                  where m.Groups["text"].Value.Equals(someString)
                  select m;

foreach (Match m in textMatches)
{
    // Do stuff
}

Note that the compiler translates a query like this...

var q = from MyType x in myEnum select x;

...into this...

var q = from x in myEnum.Cast<MyType>() select x;

...so including both the type and Cast<T>() is redundant.

Performance-wise, Cast<T>() just does an explicit type cast and yields the value, so the performance hit will be negligible. For legacy collections where you're not sure all members are of the desired type, you can use OfType<T>() instead.

查看更多
登录 后发表回答