【问题标题】:Know if TResult is empty collection知道 TResult 是否为空集合
【发布时间】:2014-07-15 17:44:38
【问题描述】:

我有这个代码

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

我想在这个方法中进行过滤,以清理大量重复的代码。

关于我应该做什么或我做错了什么有什么想法吗? 提前致谢。

【问题讨论】:

    标签: c# generics


    【解决方案1】:

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

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

    那么你就可以调用它了:

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

    【讨论】:

    • @Chorinator 被警告,这对 IEnumerable 不起作用,因为它们是两个不同的接口。
    • @Xcelled194 你错了。它适用于 IEnumerable,因为它继承自 IEnumerable。
    • 糟糕,忘记了。
    【解决方案2】:

    如果你想知道你的TResult 是否是IEnumerable,那么你只需要尝试转换它。之后您可以按如下方式处理空集合和空值:

    // 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&lt;T&gt; 和 Linq 扩展。

    【讨论】:

    • 这是最好的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 2019-12-20
    相关资源
    最近更新 更多