Mit LINQ mit Klassen nicht generische ICollection Umsetzung
-
11-09-2019 - |
Frage
Ich wollte eine LINQ-Abfrage für ein MatchCollection
Objekt laufen, aber fand dies nicht möglich war, da es nicht ICollection<T>
, nur ICollection
nicht implementiert.
Was ist die beste Option für LINQ mit nicht-generischen Sammlungen, sowohl in Bezug auf Code Prägnanz, sondern auch die Leistung und Speichernutzung?
(Bei Interesse, hier ist der Nicht-LINQuified Code:)
MatchCollection fieldValues = Regex.Matches(fieldValue, @"(?<id>\d+);#(?<text>[^;|^$]+)");
foreach (Match m in fieldValues)
{
if (m.Groups["text"].Value.Equals(someString))
{
// Do stuff
}
}
Lösung
Sie können Ihre someString
Filter mit LINQ als auch enthalten.
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
}
Beachten Sie, dass der Compiler eine Abfrage wie folgt übersetzt ...
var q = from MyType x in myEnum select x;
... in diesen ...
var q = from x in myEnum.Cast<MyType>() select x;
... so, die sowohl die Art und Cast<T>()
redundant ist.
Performance-weise, Cast<T>()
tut nur eine explizite Typumwandlung und ergibt den Wert, so wird die Leistungseinbußen vernachlässigbar. Für ältere Sammlungen, wo Sie nicht sicher sind, alle Mitglieder des gewünschten Typs sind, können Sie OfType<T>()
stattdessen verwenden können.
Andere Tipps
Versuchen Sie die Cast-Erweiterung Methode zu verwenden, die eine IEnumerable zurück.
IEnumerable<Match> query = from Match m in fieldValues.Cast<Match>()
select m;
Und Ereignis, wenn Sie auf das Cast-Verfahren nicht die Compiler verwenden, um die Art von „Abfrage“ auf IEnumerable schließen.
var query = from Match v in fieldValues
select v;