Usando LINQ com as classes que implementam ICollection não-genérico
-
11-09-2019 - |
Pergunta
Eu queria correr uma consulta LINQ contra um objeto MatchCollection
mas achamos isto não era possível, pois ele não implementa ICollection<T>
, apenas ICollection
.
O que é a melhor opção para usar LINQ com coleções não-genéricos, tanto em termos de concisão código, mas também desempenho e uso de memória?
(Se estiver interessado, aqui está o código não-LINQuified:)
MatchCollection fieldValues = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)");
foreach (Match m in fieldValues)
{
if (m.Groups["text"].Value.Equals(someString))
{
// Do stuff
}
}
Solução
Você pode incluir seu filtro someString
com LINQ também.
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 que o compilador traduz uma consulta como esta ...
var q = from MyType x in myEnum select x;
... a este ...
var q = from x in myEnum.Cast<MyType>() select x;
... então, incluindo o tipo e Cast<T>()
é redundante.
Em termos de performance, Cast<T>()
só faz um tipo de conversão explícita e produz o valor, de modo que o impacto na performance será insignificante. Para coleções legados onde você não tem certeza de todos os membros são do tipo desejado, você pode usar OfType<T>()
vez.
Outras dicas
Tente usar o método de extensão Cast que irá retornar um IEnumerable.
IEnumerable<Match> query = from Match m in fieldValues.Cast<Match>()
select m;
E evento se você não usar o método Elenco do compilador inferir o tipo de "consulta" para IEnumerable.
var query = from Match v in fieldValues
select v;