IEnumerable< T>替换糟糕的设计

本文关键字:替换 IEnumerable | 更新日期: 2023-09-27 18:11:20

我创建了以下扩展方法。这是一个糟糕的设计吗?我应该为iccollection做这个吗?

public static IEnumerable<TSource> Replace<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> newItems)
{
    return source.Except(newItems).Union(newItems);
}
public static IEnumerable<TSource> Replace<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> newItems, IEqualityComparer<TSource> comparer)
{
    return source.Except(newItems, comparer).Union(newItems, comparer);
}

更新:我觉得命名有点错。我想要这个函数做的是添加覆盖。更新:为Union添加比较器

IEnumerable< T>替换糟糕的设计

您的简化逻辑操作为

 return newItems.Union(source);
 return newItems.Union(source, comparer);

source.Except(newItems).Union(newItems)时,取source中除newItems外的所有不同项,然后加上newItems中所有不同项。这就是Union所做的!取newItems中所有不同的项,并将source中不存在的不同项相加。

您可以用不同的名称AddWithOverwriteAddWithReplace等来调用它,这些名称将是错误的(没有添加任何内容,源代码和newItems都没有以任何方式修改),但是操作本身不需要像代码那样复杂。

有权衡。使用上述方法,所有newItems都将出现在source之前。计数器显示您已经丢失了替换商品的订单。

No.

如果你看一下LINQ中原始的扩展方法,它们都使用IEnumerable<T>接口。如果您使用的是泛型集合,那么这就足够了。但是,Replace方法遗漏了要替换的成员的参数。你应该这样做:

public static IEnumerable<TSource> Replace<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> oldItems, IEnumerable<TSource> newItems)
{
    return source.Except(oldItems).Union(newItems);
}

public static IEnumerable<TSource> Replace<TSource>(this IEnumerable<TSource> source, IEnumerable<TSource> oldItems, IEnumerable<TSource> newItems, IEqualityComparer<TSource> comparer)
{
    return source.Except(oldItems, comparer).Union(newItems);
}

下面是我能想到的OverWrite方法:
    public static IEnumerable<TSource> OverWrite<TSource, TSelectItem>(this IEnumerable<TSource> source, IEnumerable<TSource> newItems, Func<TSource, TSelectItem> selectProperty) where TSource : class
    {
        IEnumerable<TSource> result = source;
        if (newItems != null)
        {
            result = source.Select(s => newItems.FirstOrDefault(n => EqualityComparer<TSelectItem>.Default.Equals(selectProperty(s), selectProperty(n))) ?? s);
        }
        return result;
    }
    public static IEnumerable<TSource> OverWrite<TSource, TSelectItem>(this IEnumerable<TSource> source, IEnumerable<TSource> newItems, Func<TSource, TSelectItem> selectProperty,IEqualityComparer<TSelectItem> propertyComparer) where TSource : class
    {
        IEnumerable<TSource> result = source;
        if (newItems != null)
        {
            result = source.Select(s => newItems.FirstOrDefault(n => propertyComparer.Equals(selectProperty(s), selectProperty(n))) ?? s);
        }
        return result;
    }

你可以这样使用:

someObjects.OverWrite(newObjects, item => item.ID);
someObjects.OverWrite(newObjects, item => item.ID, new PropertyComparer());