2010-05-14 4 views
7

Comment fonctionne OfType()?Comment fonctionne OfType <T>() Comment ça marche?

J'ai lu this link à propos de ce qui se passe mais comment exactement le fournisseur LINQ sait comment obtenir tous les objets correspondant au type spécifié. Je connais le IQueryable<T> "enchaîne" les demandes, puis évalue quand GetEnumerator() est appelée (droite?).

Spécifiquement je veux savoir comment le cadre fait-il rapidement la comparaison de type? J'ai écrit une méthode dans un projet .NET 2.0 qui est allé comme ceci (depuis 2.0 ne supporte pas ce genre de fonctionnalités):

public IEnumerable<TResult> OfType<TResult>() 
     where TResult : class 
    { 
     foreach (TItem item in this.InnerList) 
     { 
      TResult matchItem = item as TResult; 

      if (matchItem != null) 
      { 
       yield return matchItem; 
      } 
     } 
    } 

Est-ce la meilleure mise en œuvre?

EDIT: Ma principale préoccupation avec ce OfType<T>() est que c'est rapide.

Répondre

10

Votre implémentation actuelle - par sa conception - ne prend pas en charge les types de valeur.

Si vous voulez quelque chose de plus proche de la méthode OfType de LINQ, qui prend en charge tous les types, essayez ceci:

public IEnumerable<TResult> OfType<TResult>(IEnumerable source) 
{ 
    foreach (object item in source) 
    { 
     if (item is TResult) 
      yield return (TResult)item; 
    } 
} 
+0

Il est donc plus rapide d'utiliser 'is' et de lancer ou est-ce parce que vous avez inclus des types de valeur? Je pensais que l'utilisation de, puis la vérification de null est plus rapide? – TheCloudlessSky

+0

Il est possible que la différence ne soit pas pertinente en raison d'optimisations spécifiques du compilateur. –

+0

@TheCloudlessSky: Si la méthode était limitée à traiter uniquement avec des types ref, j'utiliserais la combinaison 'as'/test-for-null comme vous l'avez déjà fait. La différence de vitesse entre l'utilisation de 'is'/cast et de' as'/test-for-null sera négligeable, mais si ce niveau de micro-optimisation est important pour vous alors je vous suggère de faire un benchmarking. – LukeH

0

Cela me semble être une bonne implémentation, mais cela ressemble à une implémentation spécifique (vous faites référence à this.InnerList). Si vous avez créé une méthode d'extension (qui est prise en charge dans 2.0, n'est-ce pas?) Qui étend IEnumerable, vous seriez capable de l'utiliser sur n'importe quelle collection énumérable, n'est-ce pas?

+0

Le InnerList est en fait une « liste ». Aussi au travail nous ne pouvons pas utiliser VS2008 (ugh ...) donc nous ne pouvons pas cibler 2.0 avec le compilateur 3.5. Donc non, je ne peux pas utiliser une méthode d'extension. – TheCloudlessSky