IEnumerable是否是?更换不好的设计?

发布于 2024-12-09 08:34:08 字数 612 浏览 0 评论 0原文

我创建了以下扩展方法。 这是一个糟糕的设计吗?我应该为 ICollection 执行此操作吗?

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 添加了比较器。

I have created the following extension-methods.
Is this a bad design? Should I do this for ICollection instead?

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

Update: I think the naming is little wrong. Want I want this function to do is Add with Overwrite.
Update: Added comparer to Union.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

水染的天色ゝ 2024-12-16 08:34:08

您拥有的简化逻辑操作是

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

当您采用 source.Except(newItems).Union(newItems) 时,您将采用 source 中的所有不同项目,但 中的任何项目除外code>newItems,然后添加 newItems 中的所有不同项目。这就是 Union 所做的!获取 newItems 的所有不同项目,并将来自 source 的尚不存在的不同项目添加到其中。

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

有一些权衡。通过上述方法,所有 newItems 都将出现在 source 之前。计数器是您已经丢失了替换商品的订单。

The simplified logical operation you have is

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

When you take source.Except(newItems).Union(newItems), you take all the distinct items in source, except any item in newItems, and then add in all the distinct items in newItems. That's what Union does! Take all the distinct items of newItems and add to it the distinct items from source that do not already exist.

You can call it by a different name AddWithOverwrite, AddWithReplace, etc., and those names would be wrong (nothing is being added to anything, neither the source nor newItems are modified in any way), but the operation itself needn't be as complicated as your code makes it.

There are tradeoffs. With the approach above, all of the newItems will come before the source. The counter is that you've already lost ordering with the replaced items.

混吃等死 2024-12-16 08:34:08

不。

如果您查看 LINQ 中的原始扩展方法,它们都使用 IEnumerable 接口。如果您使用通用集合,这应该足够了。但是,您的 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());

No.

If you look at the original extension methods in LINQ, they all use IEnumerable<T> interface. If you are using generic collections, it should be enough. However your Replace method misses a parameter for members to be replaced. You should do something like this:

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

Update

Here's the OverWrite method I could come up with:

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

You can use it like this:

someObjects.OverWrite(newObjects, item => item.ID);
someObjects.OverWrite(newObjects, item => item.ID, new PropertyComparer());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文