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添加比较器
您的简化逻辑操作为
return newItems.Union(source);
return newItems.Union(source, comparer);
取source.Except(newItems).Union(newItems)
时,取source
中除newItems
外的所有不同项,然后加上newItems
中所有不同项。这就是Union
所做的!取newItems
中所有不同的项,并将source
中不存在的不同项相加。
您可以用不同的名称AddWithOverwrite
、AddWithReplace
等来调用它,这些名称将是错误的(没有添加任何内容,源代码和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());