安全地组合两个IList,占空值

时间:2017-08-15 07:15:14

标签: c#

我想将两个IList组合成一个,其中一个或两个都可以null。如果两者都是null,我希望结果为null

我有这个,但我想要一些更优雅但仍然易于阅读的东西。

private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{
    IList<Filter> result = null;

    if(first != null)
        if (second != null)
            result = first.Concat(second) as IList<Filter>;
        else
            result = first;
    else if (second != null)
        result = second;

    return result;
}

4 个答案:

答案 0 :(得分:4)

如果我用两个列表(一个可能为null)调用你的CombineFilters并返回一个副本的列表,我认为这有点奇怪。这将导致以下行为:

List<Filter> filters1 = new List<Filter>() { new Filter() };
List<Filter> filters2 = null;

Console.WriteLine(filters1.Count); // 1

var filters = CombineFilters(filters1, filters2);
filters.Add(new Filter());

Console.WriteLine(filters.Count); // 2
Console.WriteLine(filters1.Count); // also 2

我不确定我是否真的会期待这种行为。

因此,我建议您始终确保最终会有 new 列表。这使你可以做到这一点:

private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{
    return (first ?? Array.Empty<Filter>()).Concat(second ?? Array.Empty<Filter>()).ToList();
}

答案 1 :(得分:3)

Enumerable.Concate??运算符一起使用:

if(first == null && second == null)
    return null;
return Enumerable.Concat(first ?? Enumerable.Empty<IFilter>(), 
                         second ?? Enumerable.Empty<IFilter>()).ToList();

如果firstsecondnull,则会使用新列表代替concat。

我认为如果两个列表都是null,那么仍然应该返回初始化集合。在这种情况下,只需删除if语句。也可以返回IEnumerable而不是IList

private IEnumerable<Filter> CombineFilters(IEnumerable<Filter> first, IEnumerable<Filter> second)
{
    return Enumerable.Concat(first ?? Enumerable.Empty<IFilter>(), 
                             second ?? Enumerable.Empty<IFilter>());
}

返回IEnumerable而不是IList取决于您的方案。在这里阅读更多内容:

答案 2 :(得分:1)

private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{
    if (first == null && second == null) return null;
    first = first ?? new List<Filter>();
    second = second ?? new List<Filter>();
    return first.Concat(second).ToList();
}

答案 3 :(得分:1)

你可以这样做:

private IList<Filter> CombineFilters(IList<Filter> first, IList<Filter> second)
{

    if (first == null && second == null) 
    {
        return null;
    }

    return (first ?? Enumerable.Empty<Filter>())
            .Concat(second ?? Enumerable.Empty<Filter>())
            .ToList();
}

那就是说,完全避免空集合是一种很好的做法;如果没有元素,则只返回一个空集合。这样,您就不需要一直检查null。在您的情况下可能无法做到这一点,但如果是这样,它将使您的代码更加清晰。

另外,考虑使用IEnumerable<T>而不是IList<T>,因为它是更通用的抽象(并且因为IList<T>是一个破碎的,漏洞的抽象 - 实现为方法抛出异常(!)他们不支持)。另一方面,我可以看到这是一个私有方法,如果你实际上总是传递List<Filter>,那么将参数声明为List<Filter>可能更好。

编辑:
刚注意到我的答案与Gilad Green发布的one非常相似,我之前没有看到过。