为什么我在 Reflector 的 Linq 中看到如此多的代码重复?

发布于 2024-08-04 03:13:12 字数 714 浏览 5 评论 0原文

编辑:我原来的问题犯了一个错误。它应该是关于方法LastLastOrDefault(或SingleSingleOrDefault,或First 和 FirstOrDefault - 很多!)。

灵感来自 这个问题,我打开Reflector并查看了代码

Enumerable.Last<T>(this collection)

然后我跳到了代码

Enumerable.LastOrDefault<T>(this collection)

,我看到了完全相同的一段代码(大约20行),不同之处在于只有最后一行(第一个方法返回默认值(T),第二个方法抛出异常)。

我的问题是为什么会这样?为什么 Microsoft 的人允许在 .Net 框架内重复重要的代码片段?他们没有代码审查吗?

Edit: I made a mistake in my original question. It should be about methods Last and LastOrDefault (or Single and SingleOrDefault, or First and FirstOrDefault - plenty of them!).

Inspired by this question, I opened Reflector and looked at code of

Enumerable.Last<T>(this collection)

Then I jumped to code of

Enumerable.LastOrDefault<T>(this collection)

and I saw exactly the same piece of code (about 20 lines) differing in only one last line (first method returns default(T), second throws exception).

My question is why it is so? Why guys in Microsoft allow duplication of non-trivial pieces of code inside .Net framework? Don't they have code review?

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

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

发布评论

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

评论(1

蘑菇王子 2024-08-11 03:13:12

事实上,它们并不完全相同。第一个是这样的:

public static TSource Last<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) throw Error.ArgumentNull("source");

    IList<TSource> list = source as IList<TSource>;
    if (list != null) {
        int count = list.Count;
        if (count > 0) return list[count - 1];
    } else {
        using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
            if (enumerator.MoveNext()) {
                TSource current;
                do { current = enumerator.Current;}
                while (enumerator.MoveNext());

                return current;
            }
        }
    }
    throw Error.NoElements();
}

另一个是这样的:

public static TSource Last<TSource>(this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");

    TSource last = default(TSource);
    bool foundOne = false;
    foreach (TSource value in source) {
        if (predicate(value)) {
            last = value;
            foundOne = true;
        }
    }
    if (!foundOne) throw Error.NoMatch();
    return last;
}

PS:我希望我现在没有侵犯任何版权。 :S

In fact, they are not quite the same. The first is like this:

public static TSource Last<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) throw Error.ArgumentNull("source");

    IList<TSource> list = source as IList<TSource>;
    if (list != null) {
        int count = list.Count;
        if (count > 0) return list[count - 1];
    } else {
        using (IEnumerator<TSource> enumerator = source.GetEnumerator()) {
            if (enumerator.MoveNext()) {
                TSource current;
                do { current = enumerator.Current;}
                while (enumerator.MoveNext());

                return current;
            }
        }
    }
    throw Error.NoElements();
}

And the other is like this:

public static TSource Last<TSource>(this IEnumerable<TSource> source,
Func<TSource, bool> predicate)
{
    if (source == null) throw Error.ArgumentNull("source");
    if (predicate == null) throw Error.ArgumentNull("predicate");

    TSource last = default(TSource);
    bool foundOne = false;
    foreach (TSource value in source) {
        if (predicate(value)) {
            last = value;
            foundOne = true;
        }
    }
    if (!foundOne) throw Error.NoMatch();
    return last;
}

PS.: I hope I'm not breaking any copyrights now. :S

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