对 FirstOrDefault 的不同看法
IEnumerable 扩展方法 FirstOrDefault 并没有完全按照我的意愿行事,因此我创建了 FirstOrValue。这是解决这个问题的好方法还是有更好的方法?
public static T FirstOrValue<T>(this IEnumerable<T> source, Func<T, bool> predicate, T value)
{
T first = source.FirstOrDefault(predicate);
return Equals(first, default(T)) ? value : first;
}
The IEnumerable extension method FirstOrDefault didn't exactly do as I wanted so I created FirstOrValue. Is this a good way to go about this or is there a better way?
public static T FirstOrValue<T>(this IEnumerable<T> source, Func<T, bool> predicate, T value)
{
T first = source.FirstOrDefault(predicate);
return Equals(first, default(T)) ? value : first;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您的代码可能不正确;您可能还没有考虑所有情况。
当然,在我们有规范之前,我们无法知道任何代码是否正确或不正确。因此,首先编写一个单行规范:
“
FirstOrValue
接受 T 序列、谓词和 T 值,并返回序列中与谓词匹配的第一项如果有的话,或者如果没有,则为规定值。”您的尝试实际上实现了该规范吗?当然不是!测试一下:
返回-1。根据规范,正确答案是 0。与谓词匹配的第一个项目为零,因此应该返回它。
规范的正确实现如下所示:
始终先编写规范,即使它只是一个句子。
Your code is probably incorrect; you probably haven't considered all of the cases.
Of course, we cannot know if any code is correct or incorrect until we have a spec. So start by writing a one-line spec:
"
FirstOrValue<T>
takes a sequence of T, a predicate, and a value of T, and returns either the first item in the sequence that matches the predicate if there is one, or, if there is not, the stated value."Does your attempt actually implement that spec? Certainly not! Test it:
this returns -1. The correct answer according to the spec is 0. The first item that matches the predicate is zero, so it should be returned.
A correct implementation of the spec would look like:
Always write a spec first, even if it's only a single sentence.
对于引用类型,
default(T)
默认返回null
。我会这样做
default(T)
will returnnull
by default for reference types.I would do this
由于这是一个重载,因此值得一提的是没有谓词的版本。
Since this is an overload, it's worth mentioning the version with no predicate.
如果您想调整可读性而不是使用 DefaultIfEmpty,这对我来说似乎是合理的。
如果默认值的创建成本很高,您还可以创建使用 lambda 的覆盖,仅在必要时创建它。
Seems reasonable to me if you want to tweak the readability instead of using DefaultIfEmpty.
You could also create an override that uses a lambda if the creation of the default value is expensive, creating it only if necessary.