知道TResult是否为空集合

时间:2014-05-26 23:08:14

标签: c# generics

我有这段代码

public static class FallbackUtils<TResult, TRequest>
      where TRequest : IFallbackRequest
   {
      public static IEnumerable<TResult> GetAllValues(TRequest request,
         Func<TRequest, TResult> callback)          
      {
         yield return callback(request);

         while (request.CanFallback())
         {
            request.Fallback();
            yield return callback(request);
         }
      }  
   }

有时候,TResult将成为IEnumerable。在这些情况下,我希望不仅能保留null,还能保留返回的空集合。问题是我不知道怎么问TResult它是否为空我只知道如何询问它是否为空。 像这样的东西

public static IEnumerable<TResult> GetAllValues(TRequest request,
         Func<TRequest, TResult> callback, bool ignoreNullOrEmpty = false)          
      {
         var item = callback(request);

         if (ignoreNullOrEmpty)
         {
            if (item != null && item.Any())
               yield return item;
         }
         else
            yield return item;

         while (request.CanFallback())
         {
            request.Fallback();

            item = callback(request);
            if (ignoreNullOrEmpty)
            {
               if (item != null && item.Any())
                  yield return item;
            }
            else
               yield return item;
         }
      }

我想在此方法中进行过滤,以清理大量重复执行此操作的代码。

我应该做什么或者我做错了什么? 提前谢谢。

2 个答案:

答案 0 :(得分:3)

如果你需要知道TResultIEnumerable,那么你只需要尝试投射它。之后,您可以按如下方式处理空集合和空值:

// is it an IEnumerable?
var item = callback(request);
var enumerable = item as IEnumerable;
if(enumerable != null) 
{
  var enumerator = enumerable.GetEnumerator();
  if(!enumerator.MoveNext())
  {
     // handle an empty collection here
  }
  else
  {
     do 
     {
        if(enumerator.Current == null)
          // handle the null value here
     } while(enumerator.MoveNext());
  }
}

由于您可能不知道IEnumerable中的项目类型,因此您无法使用IEnumerable<T>和Linq扩展。

答案 1 :(得分:2)

Any上没有IEnumerable方法,您可以编写自己的方法:

public static bool Any(this IEnumerable source)
{
    var enumerator = source.GetEnumerator();

    return enumerator.MoveNext();
}

然后你可以打电话给它:

if (item != null && 
    item is IEnumerable && 
    ((IEnumerable)item).Any())