A different take on FirstOrDefault

前端 未结 4 1107
抹茶落季
抹茶落季 2021-02-20 14:39

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?



        
4条回答
  •  有刺的猬
    2021-02-20 15:29

    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 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:

    int x = FirstOrValue( new[] { -2, 0, 1 }, y=>y*y==y, -1);
    

    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:

    public static T FirstOrValue(this IEnumerable sequence, Func predicate, T value)
    {
        if (sequence == null) throw new ArgumentNullException("sequence");
        if (predicate == null) throw new ArgumentNullException("predicate");
        foreach(T item in sequence)
            if (predicate(item)) return item;
        return value;
    }
    

    Always write a spec first, even if it's only a single sentence.

提交回复
热议问题