我有这段代码
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;
}
}
我想在此方法中进行过滤,以清理大量重复执行此操作的代码。
我应该做什么或者我做错了什么? 提前谢谢。
答案 0 :(得分:3)
如果你需要知道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<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())