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
    }
}
È stato utile?

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top