Utilizzando LINQ con classi di attuazione ICollection non generico
-
11-09-2019 - |
Domanda
Ho voluto eseguire una query LINQ contro un oggetto MatchCollection
, ma ho trovato questo non era possibile in quanto non implementa ICollection<T>
, proprio ICollection
.
Qual è l'opzione migliore per l'utilizzo di LINQ con le collezioni non generici, sia in termini di codice di concisione, ma anche l'utilizzo delle prestazioni e della memoria?
(se interessati, ecco il codice non LINQuified:)
MatchCollection fieldValues = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)");
foreach (Match m in fieldValues)
{
if (m.Groups["text"].Value.Equals(someString))
{
// Do stuff
}
}
Soluzione
È possibile includere il filtro someString
con LINQ pure.
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
}
Si noti che il compilatore traduce una query come questa ...
var q = from MyType x in myEnum select x;
... in questo ...
var q = from x in myEnum.Cast<MyType>() select x;
... che include sia il tipo e Cast<T>()
è ridondante.
Performance-saggio, Cast<T>()
fa solo un tipo di cast esplicito e cede il valore, in modo che il colpo di prestazioni sarà trascurabile. Per le collezioni legacy in cui non siete sicuri di tutti i membri sono del tipo desiderato, è possibile utilizzare OfType<T>()
posto.
Altri suggerimenti
Provare a utilizzare il metodo di estensione Fusioni che restituirà un IEnumerable.
IEnumerable<Match> query = from Match m in fieldValues.Cast<Match>()
select m;
E evento se non si utilizza il metodo Fusioni il compilatore dedurre il tipo di "query" di IEnumerable.
var query = from Match v in fieldValues
select v;