2009-04-09 5 views
0

Vérifiez le code.Generics Sub List

class DynamicObj : BaseObj {} 
class BaseObj {} 

class clientCode 
{ 
    List<DynamicObj> GetFilteredObjs(List<BaseObj> baseList) 
    { 
     // I want to return the sublist of baseList which only have DynamicObj. 
     List<DynamicObj> dList = baseList.FindAll(
              delegate(BaseObj bo){  // Del1 
              return bo is DynamicObj; 
              }).ConvertAll<DynamicObj>(
              delegate(BaseObj bo){  // Del2 
              return bo as DynamicObj; 
              }); 

    } 
} 

Maintenant, il est peut-être une question stupide, mais mon code aura pour boucler des objets 2 fois, une fois pour boucle Del1 et une fois pour la boucle Del2.

Existe-t-il une voie directe? C# 2.0 seulement.

Répondre

2

Bien sûr:

IEnumerable<DynamicObj> GetDynamicObjects(IEnumerable<BaseObj> baseList) 
{ 
    foreach(BaseObj baseObj in baseList) 
     if(baseObj is DynamicObj) 
      yield return (DynamicObj)baseObj; 
} 

List<DynamicObj> dynamicList = new List<DynamicObj>(GetDynamicObjects(...)); 
2

La façon la plus simple est probablement d'utiliser un bloc itérateur:

public IEnumerable<TTarget> FilteredCast<TSource,TTarget> 
    (IEnumerable<TSource> source) 
    where TSource : class 
    where TTarget : class, TSource 
{ 
    foreach (TSource element in source) 
    { 
     TTarget converted = element as TTarget; 
     if (converted != null) 
     { 
      yield return converted; 
     } 
    } 
} 

(Ceci est essentiellement la méthode Enumerable.OfType dans LINQ aux objets, btw je suis restreint à faire référence à des types pour plus de commodité, mais il est encore. générique afin que vous puissiez le réutiliser plus facilement)

Puis il suffit d'écrire:.

List<DynamicObj> GetFilteredObjs(List<BaseObj> baseList) 
{ 
    return new List<DynamicObj>(FilteredCast<BaseObj,DynamicObj>(baseList); 
} 

Notez que cela ne reviendra pas nulls. Si vous voulez inclure des valeurs nulles, vous devez le faire explicitement.