Generics Sub List - PullRequest
       5

Generics Sub List

0 голосов
/ 09 апреля 2009

Проверьте код.

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;
                                             });   

   }
}

Теперь это может быть глупый вопрос, но мой код должен будет зацикливать объекты 2 раза, один раз для цикла Del1 и один раз для цикла Del2.

Есть ли прямой путь? Только C # 2.0.

Ответы [ 2 ]

2 голосов
/ 09 апреля 2009

Sure:

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 голосов
/ 09 апреля 2009

Самый простой способ - использовать блок итератора:

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;
        }
    }
}

(Между прочим, это метод Enumerable.OfType в LINQ to Objects. Кстати, я ограничил его ссылочными типами для удобства, но он все еще универсален, поэтому вы можете использовать его более легко.)

Тогда просто напишите:

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

Обратите внимание, что это не будет возвращать нули. Если вы хотите, чтобы значения NULL были включены, вам необходимо учитывать это явно.

...