Ваш код, вероятно, неверен; Вы, вероятно, не рассмотрели все случаи.
Конечно, мы не можем знать, является ли какой-либо код правильным или неправильным, пока у нас нет спецификации. Итак, начните с написания однострочной спецификации:
"FirstOrValue<T>
принимает последовательность T, предикат и значение T и возвращает либо первый элемент в последовательности, который соответствует предикату, если он есть, либо, если его нет, указанное значение . "
Ваша попытка на самом деле реализовать эту спецификацию? Конечно, нет! Проверьте это:
int x = FirstOrValue<int>( new[] { -2, 0, 1 }, y=>y*y==y, -1);
это возвращает -1. Правильный ответ согласно спецификации равен 0. Первый элемент, который соответствует предикату, равен нулю, поэтому его следует вернуть.
Правильная реализация спецификации будет выглядеть так:
public static T FirstOrValue<T>(this IEnumerable<T> sequence, Func<T, bool> 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;
}
Всегда сначала пишите спецификацию, даже если это всего лишь одно предложение.