zsharp
zsharp

Reputation: 13766

SingleOrDefault: How to change the default values?

SingleOrDefault returns null, but what if I want to assign values to represent the object that wasn't found?

Upvotes: 35

Views: 20390

Answers (4)

Joe White
Joe White

Reputation: 97808

?? operator. If the left argument is null, evaluate and return the second argument.

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

This will only work with reference types (or nullables), but it would do what you're looking for very simply.

Upvotes: 24

tvanfosson
tvanfosson

Reputation: 532605

You could create your own extension methods -- 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;
    }
}

Upvotes: 0

JaredPar
JaredPar

Reputation: 755259

You could roll your own.

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

This can be a bit expensive though because Count() requires you to process the entire collection and can be fairly expensive to run. It would be better to either call Single, catch the InvalidOperationException or roll a IsSingle method

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();
}

Upvotes: 5

oscarkuo
oscarkuo

Reputation: 10453

you can do something like

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

check out here

Upvotes: 54

Related Questions