SingleOrDefault: как изменить значения по умолчанию?

SingleOrDefault возвращает значение null, но что, если я хочу назначить значения для представления объекта, который не был найден?

Ответ 1

вы можете сделать что-то вроде

myStrings.DefaultIfEmpty("myDefaultString").Single()

просмотрите здесь

Ответ 2

?? оператор. Если левый аргумент равен нулю, оцените и верните второй аргумент.

myCollection.SingleOrDefault() ?? new[]{new Item(...)}

Это будет работать только со ссылочными типами (или с нулевыми значениями), но будет делать то, что вы ищете очень просто.

Ответ 3

Вы можете катиться самостоятельно.

public static T SingleOrDefault<T>(this IEnumerable<T> enumerable, T defaultValue) {
  if ( 1 != enumerable.Count() ) {
    return defaultValue;
  }
  return enumerable.Single();
}

Это может быть немного дорого, потому что Count() требует, чтобы вы обрабатывали всю коллекцию и могли быть довольно дорогими для запуска. Было бы лучше либо вызвать Single, поймать InvalidOperationException, либо запустить метод IsSingle

public static bool IsSingle<T>(this IEnumerable<T> enumerable) {
  using ( var e = enumerable.GetEnumerator() ) {
    return e.MoveNext() && !e.MoveNext();
  }
}

public static T SingleOrDefault<T>(this IEnumerable<T> enumerable, T defaultValue) {
  if ( !enumerable.IsSingle() ) {
    if( enumerable.IsEmpty() ) { 
      return defaultValue;
    }
    throw new InvalidOperationException("More than one element");
  }
  return enumerable.Single();
}

Ответ 4

Вы можете создать свои собственные методы расширения - SingleOrNew.

public static class IEnumerableExtensions
{
    public static T SingleOrNew<T>( this IEnumerable<T> enumeration, T newValue )
    {
        T elem = enumeration.SingleOrDefault();
        if (elem == null)
        {
            return newValue;
        }
        return elem;
    }

    public static T SingleOrNew<T>( this IEnumerable<T> enumeration, Func<T,bool> predicate, T newValue )
    {
        T elem = enumeration.SingleOrDefault( predicate );
        if (elem == null)
        {
            return newValue;
        }
        return elem;
    }
}